按值检索自定义枚举类的正确方法是什么?

时间:2010-07-31 09:45:20

标签: c# generics c#-4.0 static-methods

我在我的域模型中创建了自己的自定义伪枚举,以允许我有一些更详细的值。例如,我的课程如下:

public abstract class Enumeration<X, Y> : IComparable where X : IComparable
{

    public Enumeration(X value, Y displayName) { }

    public Y DisplayName { get { return _displayName; } }
    public X Value { get { return _value; } }

}

继承它的类将是:

public class JobType : Enumeration<string, string>
{
    public static JobType ChangeOver = new JobType("XY01", "Changeover");
    public static JobType Withdrawal = new JobType("XY02", "Withdrawal");
    public static JobType Installation = new JobType("XY03", "Installation");

    private JobType(string jobTypeId, string description)
        : base(jobTypeId, description) { }
}

我遇到的问题是我希望能够从我的存储库中的数据库返回的值中解析这些值。所以我采用的方法如下:

public static JobType Resolve(string jobTypeId) { return matchingJobType; }

我开始为每个枚举类编写一个resolve方法,但是除了在每个枚举类中使用switch语句复制相同的方法之外,还有更好的方法吗?

我考虑过向基类添加Dictionary<X, Enumeration<X, Y>> Cache;属性,并从基类的构造函数中将类添加到基类中。这也有利于确保独特的价值。我遇到的问题是,当我从字典中获取枚举时,它的类型为Enumeration<X, Y>,我希望它为JobType

所以这意味着必须在Enumeration类中添加第三个泛型类型并具有:

public static T Resolve(X value); // With the additional type
public static T Resolve<T>(X value); // Or without an additional type

我显然不喜欢写JobType.Resolve<JobType>(foo);的想法,而我想要的只是JobType.Resolve(foo);,但应该用尽可能少的代码完成。即所有这些只是从基类处理而不必包含其他泛型类型吗?

2 个答案:

答案 0 :(得分:3)

这看起来像curiously recurring template pattern的情况。如果要使基类型方法在不进行强制转换的情况下返回派生类,则可以将派生类型传递给基类型,将派生类型约束为从基类型派生,例如。

public abstract class Enumeration<TEnum, X, Y> : IComparable 
    where TEnum : Enumeration<TEnum, X, Y>
    where X : IComparable
{
    public static TEnum Resolve(X value) { /* your lookup here */ }

    // other members same as before; elided for clarity
}

然后,您可以按如下方式定义具体类。

public class JobType : Enumeration<JobType, string, string>
{
    // other members same as before; elided for clarity
}

现在,您的类型将匹配,并且基类Resolve方法不需要强制转换。

JobType type = JobType.Resolve("XY01");

如何将值存储到基类中的实例映射取决于您。听起来你已经知道如何做到这一点,并且需要一些帮助才能使类型匹配。

答案 1 :(得分:0)

您真正的枚举类可能比这更复杂,但您当前的实现看起来更简单地定义为标准枚举与DAL模式或简单的字典:

public enum JobType
{
    ChangeOver,
    Withdrawal,
    Installation,
}

// Maybe inside some DAL-pattern/database parsing class:
var databaseToJobTypeMap = new Dictionary<string, JobType>()
{
    { "XY01", JobType.ChangeOver },
    // ...
};

将解析代码保存在一起(可能带有接口抽象),您可以选择在数据存储格式/需求发生变化时切换解析器,或者最终拥有多个数据源。

如果需要解析实际的JobType值(例如,字符串“ChangeOver”或整数表示),则可以使用Enum.Parse / Enum.TryParse或cast。

您的实现似乎更不灵活,因为它将枚举类型锁定为一个字典映射样式/表示。