zoukankan      html  css  js  c++  java
  • enums in C# 转 武胜

    1、关于enum的定义
    enum Fabric
    {
    Cotton = 1,
    Silk = 2,
    Wool = 4,
    Rayon = 8,
    Other = 128
    }
    2、符号名和常数值的互相转换
      
                Fabric fab = Fabric.Cotton;
                int fabNum = (int)fab;//转换为常数值。必须使用强制转换。
                Fabric fabString = (Fabric)1;//常数值转换成符号名。如果使用ToString(),则是((Fabric)1).ToString(),注意必须有括号。

                string fabType = fab.ToString();//显示符号名
                string fabVal = fab.ToString ("D");//显示常数值
     
    3、获得所有符号名的方法(具体参见Enum类)
     
            public enum MyFamily
            {
                YANGZHIPING = 1,
                GUANGUIQIN = 2,
                YANGHAORAN = 4,
                LIWEI = 8,
                GUANGUIZHI = 16,
                LISIWEN = 32,
                LISIHUA = 64,
            }
     
                foreach (string s in Enum.GetNames(typeof(MyFamily)))
                {
                    Console.WriteLine(s);
                }
     
    4、将枚举作为位标志来处理
    根据下面的两个例子,粗略地说,一方面,设置标志[Flags]或者[FlagsAttribute],则表明要将符号名列举出来;另一方面,可以通过强制转换,将数字转换为符号名。说不准确。看下面的例子体会吧。注意:
              例一:
              Fabric fab = Fabric.Cotton | Fabric.Rayon | Fabric.Silk;
              Console.WriteLine("MyFabric = {0}", fab);//输出:Fabric.Cotton | Fabric.Rayon | Fabric.Silk;
    例二:
    class FlagsAttributeDemo
    {
        // Define an Enum without FlagsAttribute.
        enum SingleHue : short
        {
            Black = 0,
            Red = 1,
            Green = 2,
            Blue = 4
        };

        // Define an Enum with FlagsAttribute.
        [FlagsAttribute]
        enum MultiHue : short
        {
            Black = 0,
            Red = 1,
            Green = 2,
            Blue = 4
        };

        static void Main( )
        {
            Console.WriteLine(
                "This example of the FlagsAttribute attribute \n" +
                "generates the following output." );
            Console.WriteLine(
                "\nAll possible combinations of values of an \n" +
                "Enum without FlagsAttribute:\n" );
           
            // Display all possible combinations of values.
            for( int val = 0; val <= 8; val++ )
                Console.WriteLine( "{0,3} - {1}",  val, ( (SingleHue)val ).ToString( ) );

            Console.WriteLine(  "\nAll possible combinations of values of an \n" + "Enum with FlagsAttribute:\n" );
           
            // Display all possible combinations of values.
            // Also display an invalid value.
            for( int val = 0; val <= 8; val++ )
                Console.WriteLine ( "{0,3} - {1}",  val, ( (MultiHue)val ).ToString( ) );
        }
    }

    /*
    This example of the FlagsAttribute attribute
    generates the following output.

    All possible combinations of values of an
    Enum without FlagsAttribute:

      0 - Black
      1 - Red
      2 - Green
      3 - 3
      4 - Blue
      5 - 5
      6 - 6
      7 - 7
      8 - 8

    All possible combinations of values of an
    Enum with FlagsAttribute:

      0 - Black
      1 - Red
      2 - Green
      3 - Red, Green
      4 - Blue
      5 - Red, Blue
      6 - Green, Blue
      7 - Red, Green, Blue
      8 - 8
    */
    5、枚举作为函数参数。经常和switch结合起来使用。下面举例

            public static double GetPrice(Fabric fab)
            {
                switch (fab)
                {
                    case Fabric.Cotton: return (3.55);
                    case Fabric.Silk: return (5.65);
                    case Fabric.Wool: return (4.05);
                    case Fabric.Rayon: return (3.20);
                    case Fabric.Other: return (2.50);
                    default: return (0.0);
                }
            }

    6、上面三点一个完整的例子

            //1、enum的定义
            public enum Fabric : short
            {
                Cotton = 1,
                Silk = 2,
                Wool = 3,
                Rayon = 8,
                Other = 128
            }

            //将枚举作为参数传递
            public static double GetPrice(Fabric fab)
            {
                switch (fab)
                {
                    case Fabric.Cotton: return (3.55);
                    case Fabric.Silk : return (5.65);
                    case Fabric.Wool: return (4.05);
                    case Fabric.Rayon: return (3.20);
                    case Fabric.Other: return (2.50);
                    default: return (0.0);
                }
            }

            public static void Main()
            {
                Fabric fab = Fabric.Cotton;
                int fabNum = (int)fab;
                string fabType = fab.ToString();
                string fabVal = fab.ToString ("D");
                double cost = GetPrice(fab);
                Console.WriteLine("fabNum = {0}\nfabType = {1}\nfabVal = {2}\n", fabNum, fabType, fabVal);
                Console.WriteLine("cost = {0}", cost);
            }

    7、Enum类的使用

    Enum.IsDefinde、Enum.Parse两种方法经常一起使用,来确定一个值或符号是否是一个枚举的成员,然后创建一个实例。Enum.GetName打印出一个成员的值;Enum.GetNames打印出所有成员的值。其中注意typeof的使用。这一点很重要。

            public enum MyFamily
            {
                YANGZHIPING = 1,
                GUANGUIQIN = 2,
                YANGHAORAN = 4,
                LIWEI = 8,
                GUANGUIZHI = 16,
                LISIWEN = 32,
                LISIHUA = 64,
            }

                string s = "YANGHAORAN";
                if (Enum.IsDefined(typeof(MyFamily), s))
                {
                    MyFamily f = (MyFamily)Enum.Parse(typeof(MyFamily), s);
                    GetMyFamily(f);
                    Console.WriteLine("The name is:" + Enum. GetName(typeof(MyFamily), 2));
                    string[] sa = Enum.GetNames(typeof(MyFamily));
                    foreach (string ss in sa)
                    {
                        Console.WriteLine(ss);

    8. Enumeration变量的文字描述

    如果想要Enumeration返回一点有意义的string,从而用户能知道分别代表什么, 则按如下定义:
    using System.ComponentModel;
    enum Direction
    {
        [
    Description("this means facing to UP (Negtive Y)")]
        UP = 1,
        [Description("this means facing to RIGHT (Positive X)")]
        RIGHT = 2,

        [
    Description("this means facing to DOWN (Positive Y)")]
        DOWN = 3,

        [
    Description("this means facing to LEFT (Negtive X)")]
        LEFT = 4
    };

    使用如下方法来获得文字描述:
    using System.Reflection;
    using System.ComponentModel;

    public static String GetEnumDesc(Enum e)
    {
       
    FieldInfo EnumInfo = e.GetType().GetField(e.ToString());
       
    DescriptionAttribute[] EnumAttributes = (DescriptionAttribute[]) EnumInfo.
            GetCustomAttributes (
    typeof(DescriptionAttribute), false);
       
    if (EnumAttributes.Length > 0)
        {
           
    return EnumAttributes[0].Description;
        }
       
    return e.ToString();
    }

    或者可以自己定义Discription Attributes:(来自:James Geurts' Blog)
    enum Direction
    {
        [
    EnumDescription("Rover is facing to UP (Negtive Y)")]
        UP = 1,
        [
    EnumDescription("Rover is facing to DOWN (Positive Y)")]
        DOWN = 2,
       
    [EnumDescription("Rover is facing to RIGHT (Positive X)")]
        RIGHT = 3,
        [
    EnumDescription("Rover is facing to LEFT (Negtive X)")]
        LEFT = 4
    };
    AttributeUsage(AttributeTargets.Field)]
    public class EnumDescriptionAttribute : Attribute
    {
        private string _text = "";
        public string Text
        {
            get { return this._text; }
        }
        public EnumDescriptionAttribute(string text)
        {
            _text = text;
        }
    }


    Associating Strings with enums in C#

    January 17, 2008 14:50 by Luke

    I have seen other great articles out lining the benefits of some pretty clever and useful helper classes for enums. Many of these methods almost exactly mirror methods I had written in my own EnumHelper class. (Isn't it crazy when you imagine how much code duplication there must be like this out there!)

    One thing that I don't see emphasized much is trying to associated string values with enums. For example, what if you want to have a Drop Down list that you can choose from a list of values (which are backed by an enum)? Lets start with a test enum:

    public enum States
    {
    California,
    NewMexico,
    NewYork,
    SouthCarolina,
    Tennessee,
    Washington
    }

    So if you made a drop down list out of this enum, using the ToString() method, you would get a drop down that looks like this:

    image

    While most people will understand this, it should really be displayed like this:

    image

    "But enums can't have spaces in C#!" you say. Well, I like to use the System.ComponentModel.DescriptionAttribute to add a more friendly description to the enum values. The example enum can be rewritten like this:

    public enum States
    {
    California,
    [Description("New Mexico")]
    NewMexico,
    [Description("New York")]
    NewYork,
    [Description("South Carolina")]
    SouthCarolina,
    Tennessee,
    Washington
    }

    Notice that I do not put descriptions on items where the ToString() version of that item displays just fine.

    How Do We Get To the Description?

    Good question! Well, using reflection of course! Here is what the code looks like:

    public static string GetEnumDescription(Enum value)
    {
    FieldInfo fi = value.GetType().GetField(value.ToString());

    DescriptionAttribute[] attributes =
    (DescriptionAttribute[])fi.GetCustomAttributes(
    typeof(DescriptionAttribute),
    false);

    if (attributes != null &&
    attributes.Length > 0)
    return attributes[0].Description;
    else
    return
    value.ToString();
    }

    This method first looks for the presence of a DescriptionAttribute and if it doesn't find one, it just returns the ToString() of the value passed in. So

    GetEnumDescription(States.NewMexico);

    returns the string "New Mexico".

    A Free Bonus: How to Enumerate Enums

    Ok, so now we know how to get the string value of an enum. But as a free bonus, I also have a helper method that allows you to enumerate all the values of a given enum. This will allow you to easily create a drop down list based on an enum. Here is the code for that method:

    public static IEnumerable<T> EnumToList<T>()
    {
    Type enumType = typeof(T);

    // Can't use generic type constraints on value types,
    // so have to do check like this
    if (enumType.BaseType != typeof(Enum))
    throw new ArgumentException("T must be of type System.Enum");

    Array enumValArray = Enum.GetValues(enumType);
    List<T> enumValList = new List<T>(enumValArray.Length);

    foreach (int val in enumValArray)
    {
    enumValList.Add((T)Enum.Parse(enumType, val.ToString()));
    }

    return enumValList;
    }
    As you can see, the code for either of these methods isn't too complicated. But used in conjunction, they can be really useful. Here is an example of how we would create the drop down list pictured above based on our enum:
    DropDownList stateDropDown = new DropDownList();
    foreach (States state in EnumToList<States>())
    {
    stateDropDown.Items.Add(GetEnumDescription(state));
    }

    Pretty simple huh? I hope you find this as useful as I do.

    One More Example

    There is one more scenario that I often find myself needing to associate string values with enums - when dealing with legacy constant string based system. Lets say you have a library that has the following method:

    public void ExecuteAction(int value, string actionType)
    {
    if (actionType == "DELETE")
    Delete();
    else if (actionType == "UPDATE")
    Update();
    }
    (I tried to make this look as legacy as I could for a contrived example). What happens if somebody passes in "MyEvilAction" as a value for actionType? Well, whenever I see hard coded strings, that is a code smell that could possibly point to the use of enums instead. But sometimes you don't have control over legacy code and you have to deal with it. So you could make an enum which looks like this:
    public enum ActionType
    {
    [Description("DELETE")]
    Delete,
    [Description("UPDATE")]
    Update
    }
    (I know, I know, this is a very contrived example) Then you could call the ExecuteAction Method like this:
    ExecuteAction(5, GetEnumDescription(ActionType.Delete));

    This at least makes the code more readable and may also make it more consistent and secure.

  • 相关阅读:
    网页快捷键
    2016年5月3日15:55:23笔记
    【编程的乐趣-用python解算法谜题系列】谜题一 保持一致
    重温离散系列②之良序原理
    重温离散系列①之什么是证明
    浅谈栈和队列
    [leetcode]16-最接近的三数之和
    [leetcode] 4-寻找两个有序数组的中位数
    英语句子的基本结构【转】
    [leetcode] 11-盛最多水的容器
  • 原文地址:https://www.cnblogs.com/zeroone/p/1997559.html
Copyright © 2011-2022 走看看