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

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

public abstract class Enumeration : IComparable where X : IComparable { public Enumeration(X value, Y displayName) { } public Y DisplayName { get { return _displayName; } } public X Value { get { return _value; } } } 

并且inheritance它的类将是:

 public class JobType : Enumeration { 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> Cache; 属性到基类,并从基类的构造函数中将类添加到其中。 这也有利于确保独特的价值。 我遇到的问题是,当我从Dictionary中获取枚举时,它的类型为Enumeration ,我想将它作为JobType

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

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

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

这看起来像一个奇怪的重复模板模式的情况 。 如果要获取基类型方法以返回派生类而不进行强制转换,则可以将派生类型传递给基类型,将派生类型约束为从基类型派生,例如

 public abstract class Enumeration : IComparable where TEnum : Enumeration where X : IComparable { public static TEnum Resolve(X value) { /* your lookup here */ } // other members same as before; elided for clarity } 

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

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

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

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

如何将值存储到基类中的实例映射由您决定。 听起来你已经知道如何做到这一点,只需要一些帮助来获得匹配的类型。

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

 public enum JobType { ChangeOver, Withdrawal, Installation, } // Maybe inside some DAL-pattern/database parsing class: var databaseToJobTypeMap = new Dictionary() { { "XY01", JobType.ChangeOver }, // ... }; 

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

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

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