`
yyw84
  • 浏览: 77237 次
社区版块
存档分类
最新评论
阅读更多


声明:
本文内容出自:http://www.codeproject.com/useritems/DotNetEnumsNextLevel.asp
由于本人E文菜得实在离谱,对文章的“翻译”①仅限于自娱自乐,文中用词过于牵强而且漏洞百出,强烈建议读者打开上面的链接阅读原文

-------------------------------------------------------------

导言

      在这篇文章里我将对.NET中的枚举做进一步探索,本文不会含盖枚举的基本概念、语法或者使用方法(这些你可以通过MSDN得到详细的信息),最大的限制是枚举只能使用 Integer 数据类型。枚举提供了 ToString() 方法的支持,但却有限制(我会在文章后面详细论述)。主要地,我希望能够把我所列举的枚举元素不仅仅关联到整数数据,我将通过反射(Reflection)和属性(Attributes)跟使用尽量简单的例子来说明如何达到这一目标。

在 Enum 中使用 ToString()

我们先来创建一个简单的枚举。。。

public enum EmployeeType
{
    RegularEmployee,
    StoreManager,
    ChainStoreManager,
    DepartmentManager,
    Supervisor
}

我们可以通过 ToString() 方法简单地获取到下列信息

EmployeeType employee = EmployeeType.ChainStoreManager;
Console.WriteLine(employee.ToString());
Console.WriteLine(EmployeeType.ChainStoreManager.ToString());

/**//*
 输出结果: 

 ChainStoreManager 
 ChainStoreManager 
*/

但我们如何才能获取到的结果类似“Chain Store Manager”包括空格呢?我们不能去创建一个包含空格的枚举成员,否则你的代码将不能编译通过,事实上我们有很多方案可以解决这个问题。

1、在枚举成员和字符串之间创建一个映射(可以使用数组或哈希表)
2、将枚举成员 ToString() 的结果作为为键指定到资源文件
3、使用反射。。。。(我将在下面讲到)

在枚举中使用属性

我将使用属性来达到一个字符串关联到枚举成员的目的,下面通过一个简单的例子来说明这是如何做到的。

public class EnumDescriptionAttribute : Attribute
{
    
private string m_strDescription;
    
public EnumDescriptionAttribute(string strPrinterName)
    
{
        m_strDescription 
= strPrinterName;
    }


    
public string Description
    
{
        
get return m_strDescription; }
    }

}

EnumDescriptionAttribute 类继承自 Attribute,它包含一个类型为String的属性Description,下面将该属性关联到枚举 EmployeeType 的所有成员上。

public enum EmployeeType
{
    [EnumDescription(
"Regular Employee")]
    RegularEmploye,
    [EnumDescription(
"Store Manager")]
    StoreManager,
    [EnumDescription(
"Chain Store Manager")]
    ChainStoreManager,
    [EnumDescription(
"Department Manager")]
    DepartmentManager,
    [EnumDescription(
"On Floor Supervisor")]
    Supervisor
}


从枚举获取到属性的值


为了获取到属性的值,我必须使用到反射,下是是一个简单的例子:

// setup the enum
EmployeeType employee = EmployeeType.ChainStoreManager;

// get the field informaiton
FieldInfo fieldInfo = employee.GetType().GetField("ChainStoreManager");

// get the attributes for the enum field
object[] attribArray = fieldInfo.GetCustomAttributes(false);

// cast the one and only attribute to EnumDescriptionAttribute
EnumDescriptionAttribute attrib = (EnumDescriptionAttribute)attribArray[0];

// write the description
console.WriteLine("Description: {0}", attrib.Description);

/**//*
 输入结果: 
 Chain Store Manager
*/
 

其中最重点的一行代码:FieldInfo fieldInfo = employee.GetType().GetField("ChainStoreManager"); 我们注意硬编码到里面的枚举成员名称ChainStoreManager实际上可以通过 ToString() 方法来代替。

一个获取描述信息的通用方法

其中使用了 ToString() 方法

public static string GetEnumDescription(Enum enumObj)
{
    System.Reflection.FieldInfo fieldInfo 
= enumObj.GetType().GetField(enumObj.ToString());

    
object[] attribArray = fieldInfo.GetCustomAttributes(false);
    
if (attribArray.Length == 0)
    
{
        
return String.Empty;
    }

    
else
    
{
        EnumDescriptionAttribute attrib 
= attribArray[0as EnumDescriptionAttribute;

        
return attrib.Description;
    }

}


让枚举成员关联到更多的数据类型


到目前为止我们仅仅在我们的枚举成员中添加了描述信息,不过我们是完全可以让我们的枚举关联到任何一种数据类型的,我交将创建一个新的枚举来展示我的想法(这跟前面的做法一样)。

public enum ManagerType
{
    StoreManager,
    ChainManager,
    Superivor
}

而且我还得创建一个 EnumDescription 的派生类 ManagerAttribute,跟提供两个价格信息(最高和最低薪水值)

public class ManagerAttribute : EnumDescriptionAttribute
{
    
private int m_intMinSalary;
    
private int m_intMaxSalary;
    
public ManagerAttribute(string strDescription, int intMinSalary, int intMaxSalary)
        : 
base(strDescription)
    
{
        m_intMinSalary 
= intMinSalary;
        m_intMaxSalary 
= intMaxSalary;
    }


    
public ManagerAttribute(string strDescription)
        : 
base(strDescription)
    
{
    }


    
public int MinSalary
    
{
        
get return m_intMinSalary; }
        
set { m_intMinSalary = value; }
    }

    
public int MaxSalary
    
{
        
get return m_intMaxSalary; }
        
set { m_intMaxSalary = value; }
    }

}

现在我将 ManagerAttribute 关联到所有枚举成员上,为了让代码的可读性更强,给 ManagerAttributes 的所有属性都附了值。

public enum ManagerType
{
    [Manager(
"Store Manager", MinSalary=40000, MaxSalary=100000)]
    StoreManager,
    [Manager(
"Chain Manager", MinSalary=50000, MaxSalary=110000)]
    ChainManager,
    [Manager(
"Store Supervisor", MinSalary=30000, MaxSalary=50000)]
    Superivor
}

下一步是改进获取 EnumDescriptionAttribute 属性值的通用方法,让它支持所有数据类型,使用C# 2.0 中的泛型(Generics)很容易办到

public static T GetAttribute<T>(Enum enumObj) where T : EnumDescriptionAttribute
{
    
// get field informaiton for our enum element
    FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());

    
// get all the attributes associated with our enum
    object[] attribArray = fieldInfo.GetCustomAttributes(false);

    
if (attribArray.Length == 0)
        
return default(T);
    
else
    
{
        
// cast the attribute and return it
        T attrib = (T)attribArray[0];
        
if (attrib != null)
            
return attrib;
        
else
            
return default(T);
    }

}


工具方法

到目前为止我们已经写了两个工具类,一个是简单地实现了从枚举中获取描述信息,另一个继承自 EnumDescriptionAttribute 的更通用的方法可以获取任何数据类型的属性值,你可以把它们添加到你的枚举工具类(如:EnumHelper)中去,这里我还是简单地把它放在 EnumDescriptionAttribute 中。

public class EnumDescriptionAttribute  : Attribute
{
    
private string m_strDescription;
    
public EnumDescriptionAttribute(string strEnumDescription)
    
{
        m_strDescription 
= strEnumDescription;
    }


    
public string Description get return m_strDescription; } }

    
public static string GetEnumDescription(Enum enumObj)
    
{
        System.Reflection.FieldInfo fieldInfo 
= enumObj.GetType().GetField(enumObj.ToString());
        
object[] attribArray = fieldInfo.GetCustomAttributes(false);
        
if (attribArray.Length == 0)
            
return String.Empty;
        
else
分享到:
评论

相关推荐

    vb.net教程,word版

    在VB.NET中,"枚举(Enum)"是一个重要的数据类型,它允许我们定义一组命名的常量。这些常量便于编程,因为它们提供了可读性更强的代码,同时减少了因手动输入错误值而导致的潜在错误。枚举是基于特定的基础数据类型...

    dotnet-EnumsNET是一个高性能类型安全的NETenum工具类库

    Enums.NET是一个高性能类型安全的.NET enum工具类库

    CSharp 3.0 With the .NET Framework 3.5 Unleashed(english)

    1 Introducing the .NET Platform 38 What Is .NET? 38 The Common Language Runtime (CLR) 40 The .NET Framework Class Library (FCL) 43 C# and Other .NET Languages 45 The Common Type System (CTS...

    vb.net 数据类型

    VB.NET 是一种面向对象的编程语言,其数据类型是编程的基础,用于定义变量的存储和行为。本篇文章将深入探讨VB.NET中的基本数据类型,包括字符类型、数值类型和其他特定类型,以及枚举类型和用户自定义类型的使用。 ...

    VB.Net图解入门教程

    VB.Net 的基本语法结构包括Imports、Namespace、Class、Module、Interface、Enum、Delegate 等。其中,Imports 语句用于引入外部命名空间,Namespace 用于定义命名空间,Class 用于定义类,Module 用于定义模块,...

    .net平台DOM解析实例

    public enum PlayerStatus { Active, Injured, Retired } ``` 然后,在处理DOM时,可以用这个枚举来设置或检查球员的状态属性。 总的来说,`.NET平台DOM解析实例`涵盖了XML解析的基础知识,包括加载XML、遍历DOM...

    vb.net读写USB接口数据

    在VB.NET编程环境中,与USB设备进行交互是一个常见的任务,特别是在开发硬件驱动或者控制系统时。本文将详细讲解如何使用VB.NET来实现USB接口的数据读写,并自动检测USB设备的在线状态。 首先,我们需要理解USB通信...

    asp.net复习题

    6. **枚举(ENUM)**: 枚举是一种常量集合,选项C错误是因为不能直接赋值整数5给枚举变量,而应使用枚举成员。 7. **数组声明**: 正确的数组声明是选项A,其他选项没有正确初始化数组或语法错误。 8. **引用参数(REF...

    【ASP.NET编程知识】.NET获取枚举DescriptionAttribute描述信息性能改进的多种方法.docx

    .NET 获取枚举 DescriptionAttribute 描述信息性能改进的多种方法 在 ASP.NET 编程中,获取枚举 DescriptionAttribute 描述信息是一个常见的需求。DescriptionAttribute 特性可以用于 many places,例如枚举,通过...

    [VB.NET源码]全局鼠标

    【VB.NET源码】全局鼠标 在VB.NET编程中,有时候我们需要实现全局鼠标事件的监听,比如跟踪鼠标的移动、点击等操作,即使鼠标焦点不在我们的应用程序上也能够捕获这些事件。这就是全局鼠标钩子(Global Mouse Hook...

    vb.net高级开发指南

    2. 枚举与结构:枚举(Enum)用于定义一组相关的命名常量,方便代码的可读性。结构(Structure)是一种轻量级的数据类型,不同于类,它们是值类型,适用于存储简单数据。 3. 泛型:泛型允许在不指定具体类型的情况...

    C#.NET编程规范

    C#.NET 编程规范是指导开发者遵循的一套标准,以确保代码的可读性、可维护性和一致性。本文档主要介绍了C#.NET中的命名约定、注释规范以及一些基本的编程实践。 **命名约定** 1. **PascalCase 和 CamelCase**: -...

    C#.Net开发规范

    C#.Net是微软公司推出的一种面向对象的编程语言,它基于.NET Framework或.NET Core平台,广泛应用于构建桌面应用、Web应用、移动应用以及游戏开发等多个领域。C#.Net的开发规范是为了确保代码的质量、可读性、可维护...

    .net 面试题(.net程序员面试必看)

    - 枚举(Enum):了解如何创建和使用枚举类型。 - 委托(Delegate)与事件(Event):用于处理异步操作和回调机制。 - Lambda表达式:简化匿名方法的编写,常用于LINQ查询。 - 异常处理:掌握try-catch-finally...

    .net面试的一些试题

    - 枚举(Enum)和结构(Struct):了解它们的区别,何时使用枚举,何时选择结构。 - 异常处理:理解try-catch-finally语句块,以及如何自定义异常。 - 泛型:了解泛型的作用,如减少类型转换,提高代码复用。 2....

    VB.net编程基础

    VB.NET使用关键字`Dim`声明变量,`If...Then...Else`进行条件判断,`For...Next`和`While...End While`用于循环。 ### 3. 类与对象 在VB.NET中,类是创建对象的蓝图,而对象是类的实例。通过`Class`关键字定义类,...

    [ASP.NET.AJAX编程参考手册(涵盖ASP.NET.3.5及2.0)].(美)霍斯拉维.扫描版.pdf

    中文名: ASP.NET AJAX编程参考手册(涵盖ASP.NET 3.5及2.0) 原名: ASP.NET AJAX Programmer's Reference 作者: (美)霍斯拉维 译者: 刘志忠 图书分类: 软件 资源格式: PDF 版本: 扫描版 出版社: 清华大学出版社 书号...

    亮剑.NET深入体验与实战精要2

    《.NET深入体验与实战精要》作者身为从事.NET一线开发的资深开发专家,常年耕耘技术博客,惠及无数.NET新知。此次将长期的思考、感悟,多年的系统开发、设计和团队管理经验,以及深入分析众多项目实战的宝贵成果...

    C#.NET教程(基础)

    C#.NET 是一种由微软开发的面向对象的编程语言,它是.NET框架的一部分,为开发者提供了构建各种类型的应用程序的能力,包括桌面应用、Web应用以及移动应用等。本教程旨在为初学者提供一个全面且基础的C#.NET学习路径...

    贪吃蛇游戏(编程语言vb.net)

    9. **状态管理**:游戏有开始、运行、暂停和结束等状态,可以使用枚举类型(Enum)来表示这些状态,并在状态机模型中切换状态。 10. **资源管理**:游戏可能需要使用图像、声音等资源,VB.NET提供了对这些资源的...

Global site tag (gtag.js) - Google Analytics