使用用户定义的转换将字符串转换为type-safe-enum

Mel*_*lle 5 c# dictionary

为了将Enum与字符串结合使用,我实现了一个基于/sf/answers/29709011/的StringEnum类.

但是,当我尝试实现建议的用户定义转换操作时,我遇到了问题.

StringEnum类定义如下:

public abstract class StringEnum
{
    private readonly String name;
    private readonly int value;

    protected static Dictionary<string, StringEnum> instances
        = new Dictionary<string, StringEnum>();

    protected StringEnum(int value, string name)
    {
        this.value = value;
        this.name = name;
        instances.Add(name.ToLower(), this);
    }

    public static explicit operator StringEnum(string name)
    {
        StringEnum se;
        if (instances.TryGetValue(name.ToLower(), out se))
        {
            return se;
        }
        throw new InvalidCastException();
    }

    public override string ToString()
    {
        return name;
    }
}
Run Code Online (Sandbox Code Playgroud)

我像这样使用这个类作为基类:

public class DerivedStringEnum : StringEnum
{
    public static readonly DerivedStringEnum EnumValue1
        = new DerivedStringEnum (0, "EnumValue1");
    public static readonly DerivedStringEnum EnumValue2
        = new DerivedStringEnum (1, "EnumValue2");

    private DerivedStringEnum (int value, string name) : base(value, name) { }
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用它时

string s = "EnumValue1"
DerivedStringEnum e = (DerivedStringEnum) s;
Run Code Online (Sandbox Code Playgroud)

返回InvalidCastException.检查代码显示StringEnum类的instances属性永远不会被填充.

有没有一种简单的方法来解决这个问题?

我不喜欢使用C#属性"magic",如[StringValue("EnumValue1")].

谢谢!

And*_*tan 6

您还必须在派生类上定义显式强制转换运算符.预计基类不知道如何转换为派生类.

由于运算符是静态的,因此它们不是继承的 - 显式转换运算符仅在string和之间定义StringEnum.你可以自己做这个相当难看的双重演员:

DerivedStringEnum e = (DerivedStringEnum)(StringEnum)s
Run Code Online (Sandbox Code Playgroud)

或者在你的派生类中你可以放:(在@ili指出我自己的疏忽后编辑)

public static explicit operator DerivedStringEnum(string name) 
{ 
  return (DerivedStringEnum)(StringEnum)name; 
} 
Run Code Online (Sandbox Code Playgroud)