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]
Session["variable"]
to anSBool
instead of a string? Or to astring
and then anSBool
? – SoftwaresBool.False
is a Boolean correct...? if you are checking if it's equal why not cast that value on the right side of the==
toif( ( (string)Session["variable"] ) == SBool.False.ToString()
TheCasting error is correct btw
– Sibylle(string)Session["variable"]
– High(string)
should not throw exceptions; ifSession["var"]
is invalid it will simply return "" - citation @DJKRAZE: the point is to not have to ToString every time. that's why I'm using an implicit cast in the first place. – BoehmiteSession
may contain object of absolutely any type, so you can easily get InvalidCastException. Just separate your expression in two lines and check which one throws Exception – HighSession["var"] = SBool.True;
would not use the cast. Thanks for the illuminate; that explains the whole issue. – Boehmite