Reputation: 27703
I know there is a way to make enum work for string types with conversions galore - the code doesn't look pretty.
Does anyone know of any way to have something like this:
public SOMESTRUCTURE SessionKeys : string
{
value1 = "value1key",
value2 = "value2key",
name = "name"
}
so later in my code I could refer to it as:
SessionKeys.value1
Upvotes: 4
Views: 3290
Reputation: 415735
See my answer here:
Getting static field values of a type using reflection
The difference between this and John Fisher's answer is that you can pass SessionKeys as function parameters and get the enum-like semantics you want.
The previous question asked for VB.Net, but a C# port shouldn't be that hard. In fact, here (untested):
public interface ICustomEnum<T>
{
ICustomEnum<T> FromT(T value);
T Value { get; }
// Implement using a sealed class with a private constructor
// that accepts and sets the Value property,
// one shared readonly property for each desired value in the enum,
// and implicit conversions to and from T.
// Then see this link to get intellisense support
// that exactly matches a normal enum:
// https://stackoverflow.com/questions/102084/hidden-features-of-vb-net/102217#102217
// Note that the completion list only works for VB.
}
/// <completionlist cref="SessionKeys"/>
public sealed SessionKeys: ICustomEnum<string>
{
private string _value;
public string Value { get { return _value; } }
private SessionKeys(string value)
{
_value = value;
}
private static SessionKeys _value1 = new MyStringEnum("value1key");
public static SessionKeys value1 { get { return _value1;} }
private static MyStringEnum _value2 = new MyStringEnum("value2key");
public static MyStringEnum value2 { get { return _value2;} }
public static ICustomEnum<string> FromString(string value)
{
// use reflection or a dictionary here if you have a lot of values
switch( value )
{
case "value1key":
return value1;
case "value2key":
return value2;
default:
return null; //or throw an exception
}
}
public ICustomEnum<string> FromT(string value)
{
return FromString(value);
}
public static implicit operator string(SessionKeys item)
{
return item.Value;
}
public static implicit operator SessionKeys(string value)
{
return FromString(value);
}
}
You don't really need the interface, but I keep it to remind me how to implement them.
Upvotes: 3
Reputation: 1359
The thing is that an enum isn't just a static class with a bunch of public numerical constants. An enum is a Type. With constants you lose type safety. You can achieve type safety if you make the static members of your class the same type as the class.
public sealed class SessionKey
{
private _value;
private SessionKey( string value )
{
_value = value;
}
public string Value { get return _value; }
public static readonly SessionKey Value1 = new SessionKey( "Value1" );
public static readonly SessionKey Value2 = new SessionKey( "Value2" );
}
public class Something
{
/* stuff */
public void Foo( SessionKey sessionKey )
{
switch( sessionKey.Value )
{
case SessionKey.Value1.Value:
DoBaz();
break;
case SessionKey.Value2.Value:
DoBop();
break;
default:
DoBar();
}
}
/* other stuff */
}
Upvotes: 1
Reputation: 564413
Using C# 2.0 - I believe the best option is to use a static class with constants for your values, as suggested by John Fisher.
If you can use C# 3.0, you could use a standard enum, and a simple extension method to handle the conversion in a less objectionable manner.
Upvotes: 3
Reputation: 22719
This is about the best I've come up with. (I haven't compiled it, so the syntax may be off.)
public static class SessionKeys
{
public const string Value1 = "Value1";
public const string Value2 = "Value2";
...
}
Upvotes: 10