Alright, I've been trying to find any information on this for a while. I built a small class to see how hard type-safe-enums are to implement for strings, because I want to use them for database field-names and such. I've never liked the fact that enums could only be used for integers.
However, even though I have implemented an implicit operator
for this class, every time I try to use it, it gives me an invalid cast exception. I'm at a loss, as I can see nothing wrong with my code at this point.
Here's the class:
/// <summary>
/// SBool - type-safe-enum for boolean strings
/// </summary>
public sealed class SBool
{
private readonly String name;
private readonly int value;
// these guys were for conversions. They might work better in another case,
// but for this one, they weren't very helpful.
// ((I.e. they didn't work either.))
//private static readonly Dictionary<SBool, String> stringsByBool = new Dictionary<SBool, String>();
//private static readonly Dictionary<String, SBool> boolsByString = new Dictionary<String, SBool>();
public static readonly SBool True = new SBool( 1, "true" );
public static readonly SBool False = new SBool( 0, "false" );
private SBool( int value, String name )
{
this.name = name;
this.value = value;
//stringsByBool[this] = name;
//boolsByString[name] = this;
}
private SBool( SBool sbool )
{
this.name = sbool.name;
this.value = sbool.value;
//stringsByBool[this] = name;
//boolsByString[name] = this;
}
public override String ToString()
{
return name;
}
/// <summary>
/// allows implicit casting of SBools to strings
/// </summary>
/// <param name="sbool">the SBool to cast into a string</param>
/// <returns>the string equivalent of the SBool (its value)</returns>
public static implicit operator String( SBool sbool )
{
if ( sbool == SBool.True )
return SBool.True.name;
else
return SBool.False.name;
}
/// <summary>
/// implicitly cast a string into a SBool.
/// </summary>
/// <param name="str">the string to attempt to cast as a SBool</param>
/// <returns>the SBool equivalent of the string,
/// SBool.False if not either "true" or "false".</returns>
public static explicit operator SBool( String str )
{
if ( !String.IsNullOrEmpty(str) && str.ToLower() == "true" )
return SBool.True;
else
return SBool.False;
}
public static bool operator ==( SBool left, SBool right )
{
return left.value == right.value;
}
public static bool operator !=( SBool left, SBool right )
{
return left.value != right.value;
}
}
This is failing on the check of a Session variable:if( ( (string)Session["variable"] ) == SBool.False )
with an InvalidCastException,
and I quite frankly have no idea why.
Thanks in advance; cookies for anyone who can explain why this doesn't work (cookies not available in all areas). I'm going to get other things fixed, but let me know if there's anything that is unclear. For more info on Type-Safe enums, here's one of the SO posts I based this class off of.
[MetaEDIT] disregard this. I was horribly, horribly mistaken. [/edit]
As Servy mentioned these types of cast happen at compile time. However there is a way to force this check to occur at runtime by using dynamic keyword. Instead of casting to SBool cast to dynamic. This will cause cast operators to be executed at run time.
In my opinion casting to SBool is a cleaner and less error prone solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With