基于类的枚举实现

分享于 

6分钟阅读

Web开发

  繁體 雙語

介绍

ClassEnum 库是一种基于类的枚举实现,其中语言 enum 无法完成该任务。

为什么使用 ClassEnum

C# enum 非常方便,但是它只能有一个没有空格和特殊字符的string NAME。

一个简单的例子说明为什么我们需要实现一个类可以是信用卡类型。 共有 4种常用信用卡类型: Visa,Master,美国运通和Discover卡。 如果使用 C# enum 表示这些类型,则必须使用AmericanExpress和DiscoverCard作为 enum NAME,当你尝试显示它们时会很麻烦。
基于类的枚举实现很简单。 它使用类的static 只读字段作为枚举项,并将构造函数声明为 private 以使它的安全。 下面是一个基于类的信用卡类型枚举的示例:

publicsealedclass CreditCardType {
 publicstaticreadonly CreditCardType AmericanExpress =
 new CreditCardType("American Express");
 publicstaticreadonly CreditCardType DiscoverCard =
 new CreditCardType("Discover Card");
 publicstaticreadonly CreditCardType Master = new CreditCardType("Master");
 publicstaticreadonly CreditCardType Visa = new CreditCardType("Visa");
 privatereadonlystring name;
 private CreditCardType(string name) {
 this.name = name;
 }
 publicoverridestring ToString() {
 return name;
 }
}

此类实现的强大功能是,如果需要,可以添加属性甚至函数。 这里缺少的东西是 Enum.Parse 函数,它允许你从 string 解析 enum 类型。 同样这个基于类的枚举需要能够在 NHibernate 中映射。 ClassEnum 库提供了一个基类,用于创建基于类的枚举,其中包含一些基本函数,如 ParseNHiberante 用户类型。

ClassEnum 易于使用。 通过继承 ClassEnumGeneric<T> 抽象类创建你自己的基于类的枚举。 T 是基于类的枚举的类型。

publicclass CreditCardType : ClassEnumGeneric<CreditCardType>
{
 publicreadonlystatic CreditCardType Visa = new CreditCardType("Visa");
 publicreadonlystatic CreditCardType AmericanExpress = new CreditCardType("American Express");
 private CreditCardType(string name):base(name) {}
}

现在 CreditCardType 自动从 ClassEnumGeneric 继承有用的函数和属性:

// static parse functionCreditCardType.Parse("Visa"); //returns CreditCardType.Visa// static Items property that returns a collection that contains// CredictCardType.Visa and CredictCardType.AmericanExpress// and other CredictCardTypesif declared.CreditCardType.Items; //returns a collection that contains

ClassEnum 实现可以更强大,因为你可以在基于类的实现中使用继承和多态性。 以下是一个示例:

publicclass CreditCardType : ClassEnumGeneric<CreditCardType> {
 publicreadonlystatic CreditCardType Visa = new Visa();
 publicreadonlystatic CreditCardType AmericanExpress = new AmericanExpress();
 protected CreditCardType(string name) : base(name) {}
 publicabstractbool ValidateCCNumber(string ccNumber);
 privateclass Visa : CreditCardType {
 public Visa() : base("Visa") {}
 publicoverridebool ValidateCCNumber(string ccNumber){
 //....do some Visa validation }
 }
 privateclass AmericanExpress : CreditCardType {
 public AmericanExpress() : base("American Express") {}
 publicoverridebool ValidateCCNumber(string ccNumber){
 //....do some AmericanExpress validation }
 }
 }

现在,你需要使用 ClassEnum 基类的另一个主要原因。 ClassEnum 组件还提供 NHibernate usertype,以便你可以像映射 enum 属性一样,在 NHibernate 中映射 ClassEnum 属性。 你所需要做的就是在 ClassEnum 程序集中继承通用 ClassEnumUserType 基类来声明一个 NHibernate usertype。

publicclass CreditCardTypeUserType : ClassEnumUserType<CreditCardType>{}

现在你可以使用以下 Hbm 映射XML示例来映射你的属性:

<propertyname="CCType"type="YourNameSpace.CreditCardTypeUserType,
 YourAssembly"column="CCTypeEnum"/>

如何使用

ClassEnum 程序集是 MindLib 项目的一部分。 你可以在 /src 文件夹中下载MindLib源软件包( 在其中你将找到/src。 另外,在解决方案中,可以找到 单元测试 ClassEnum.Test 项目,其中有更多的示例代码可以显示如何使用这个 ClassEnum 库。


相关文章