C# 以与枚举相同的方式将字符串值存储为常量

C# 以与枚举相同的方式将字符串值存储为常量,c#,.net,.net-2.0,enums,constants,C#,.net,.net 2.0,Enums,Constants,我知道有一种方法可以让enum在大量转换的字符串类型中工作——代码看起来并不漂亮 有人知道有什么方法可以得到这样的东西吗: public SOMESTRUCTURE SessionKeys : string { value1 = "value1key", value2 = "value2key", name = "name" } 因此,在稍后的代码中,我可以将其称为: SessionKeys.value1 这大概是我想到的最好的了。(我还没有编译它,所以语法可

我知道有一种方法可以让enum在大量转换的字符串类型中工作——代码看起来并不漂亮

有人知道有什么方法可以得到这样的东西吗:

    public SOMESTRUCTURE SessionKeys : string
{
    value1 = "value1key",
    value2 = "value2key",
    name = "name"
}
因此,在稍后的代码中,我可以将其称为:

SessionKeys.value1

这大概是我想到的最好的了。(我还没有编译它,所以语法可能不正确。)

使用C#2.0——我认为最好的选择是使用一个静态类,该类的值带有常量,如所建议的

如果您可以使用C#3.0,那么您可以使用标准枚举和简单的扩展方法以一种不那么令人讨厌的方式处理转换。

请参见我的答案:

这与John Fisher的答案之间的区别在于,您可以将SessionKeys作为函数参数传递,并获得所需的类似枚举的语义

上一个问题问的是VB.Net,但C#port不应该那么难。事实上,这里(未经测试):

公共接口ICustomeum
{
icustomenumfromt(T值);
T值{get;}
//使用带有私有构造函数的密封类实现
//接受并设置Value属性,
//枚举中每个所需值的一个共享只读属性,
//以及与T之间的隐式转换。
//然后查看此链接以获得intellisense支持
//与正常枚举完全匹配的:
// https://stackoverflow.com/questions/102084/hidden-features-of-vb-net/102217#102217
//请注意,完成列表仅适用于VB。
}
/// 
公开密封的会话密钥:ICustomEnum
{
私有字符串_值;
公共字符串值{get{return{u Value;}}
专用会话密钥(字符串值)
{
_价值=价值;
}
private static SessionKeys_value1=new MyStringEnum(“value1key”);
publicstaticsessionkeys值1{get{return{u value1;}}
私有静态MyStringEnum_value2=新的MyStringEnum(“value2key”);
公共静态MyStringEnum value2{get{return\u value2;}}
公共静态ICustomEnum FromString(字符串值)
{
//如果您有很多值,请在此处使用反射或字典
开关(值)
{
案例“value1key”:
返回值1;
案例“value2key”:
返回值2;
违约:
返回null;//或引发异常
}
}
公共ICustomEnum FromT(字符串值)
{
返回字符串(值);
}
公共静态隐式运算符字符串(SessionKeys项)
{
返回项。值;
}
公共静态隐式运算符SessionKeys(字符串值)
{
返回字符串(值);
}
}

你并不真的需要这个接口,但我保留它是为了提醒我如何实现它们。

问题是,枚举不仅仅是一个带有一堆公共数值常量的静态类。枚举是一种类型。使用常量会失去类型安全性。如果使类的静态成员与类的类型相同,则可以实现类型安全

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 */
}

是的,我在考虑使用静态类。这么干净。我只是想也许还有其他一些我不知道的选项。这里的问题是,要将其中一个值传递给函数,必须使用一个普通的旧字符串参数,因此编译器当然会允许该函数使用任何字符串。@Joel Coehoorn,gnomixa:您可以创建自己的类型,虽然那要混乱得多。您还可以提供一个字典来验证它是否是有效的“SessionKey”@gnomixa:另外,请参见有关您的命名的链接:
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);
    }
}
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 */
}