国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

c# enmu 枚舉小結(jié)(1)

2019-11-17 03:56:13
字體:
供稿:網(wǎng)友
枚舉
  枚舉類型聲明為一組相關(guān)的符號(hào)常數(shù)定義了一個(gè)類型名稱。枚舉用于“多項(xiàng)選擇”場合,就是程序運(yùn)行時(shí)從編譯時(shí)已經(jīng)設(shè)定的固定數(shù)目的“選擇”中做出決定。

  枚舉類型(也稱為枚舉)為定義一組可以賦給變量的命名整數(shù)常量提供了一種有效的方法。例如,假設(shè)您必須定義一個(gè)變量,該變量的值表示一周中的一天。該變量只能存儲(chǔ)七個(gè)有意義的值。若要定義這些值,可以使用枚舉類型。枚舉類型是使用 enum 關(guān)鍵字聲明的。

enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };

默認(rèn)情況下,枚舉中每個(gè)元素的基礎(chǔ)類型是 int。可以使用冒號(hào)指定另一種整數(shù)值類型。
如果不為枚舉數(shù)列表中的元素指定值,則它們的值將以 1 為增量自動(dòng)遞增。在前面的示例中,Days.Sunday 的值為 0,Days.Monday 的值為 1,依此類推。創(chuàng)建新的 Days 對(duì)象時(shí),如果不顯式為其賦值,則它將具有默認(rèn)值 Days.Sunday (0)。創(chuàng)建枚舉時(shí),應(yīng)選擇最合理的默認(rèn)值并賦給它一個(gè)零值。這便使得只要在創(chuàng)建枚舉時(shí)未為其顯式賦值,則所創(chuàng)建的全部枚舉都將具有該默認(rèn)值。枚舉中大小寫敏感,但是建議不要這樣。

枚舉的優(yōu)點(diǎn):
<1>枚舉可以使代碼更易于維護(hù),有助于確保給變量指定合法的、期望的值。

<2>枚舉使代碼更清晰,允許用描述性的名稱表示整數(shù)值,而不是用含義模糊的數(shù)來表示。

<3>枚舉使代碼更易于鍵入。在給枚舉類型的實(shí)例賦值時(shí),VS.NET IDE會(huì)通過IntelliSense彈出一個(gè)包含可接受值的列表框,減少了按鍵次數(shù),并能夠讓我們回憶起可能的值

枚舉實(shí)例

  聲明:



public enum TimeOfDay
{
    Moning = 0,
    Afternoon = 1,
    Evening = 2,
};


  使用:



    public string getTimeOfDay(TimeOfDay time)
    {
        string result = string.Empty;
        switch (time)
        {
            case TimeOfDay.Moning:
                result = "上午";
                break;
            case TimeOfDay.Afternoon:
                result = "下午";
                break;
            case TimeOfDay.Evening:
                result = "晚上";
                break;
            default:
                result = "未知";
                break;
        }
        return result;
    }


枚舉方法



  <1>獲取枚舉字符串



TimeOfDay time = TimeOfDay.Afternoon;

Console.WriteLine(time.ToString());//輸出:Afternoon





  <2>Enum.Parse()方法。這個(gè)方法帶3個(gè)參數(shù),第一個(gè)參數(shù)是要使用的枚舉類型。其語法是關(guān)鍵字typeof后跟放在括號(hào)中的枚舉類名。typeof運(yùn)算符將在第5章詳細(xì)論述。第二個(gè)參數(shù)是要轉(zhuǎn)換的字符串,第三個(gè)參數(shù)是一個(gè)bool,指定在進(jìn)行轉(zhuǎn)換時(shí)是否忽略大小寫。最后,注意Enum.Parse()方法實(shí)際上返回一個(gè)對(duì)象引用—— 我們需要把這個(gè)字符串顯式轉(zhuǎn)換為需要的枚舉類型(這是一個(gè)取消裝箱操作的例子)。對(duì)于上面的代碼,將返回1,作為一個(gè)對(duì)象,對(duì)應(yīng)于TimeOfDay.Afternoon的枚舉值。在顯式轉(zhuǎn)換為int時(shí),會(huì)再次生成1。



TimeOfDay time2 = (TimeOfDay) Enum.Parse(typeof(TimeOfDay), "afternoon", true);

Console.WriteLine((int)time2);//輸出1







  <3>得到枚舉的某一值對(duì)應(yīng)的名稱

lbOne.Text = Enum.GetName(typeof(TimeOfDay), 0);
    <4>得到枚舉的所有的值

foreach (int i in Enum.GetValues(typeof(TimeOfDay)))
            lbValues.Text += i.ToString();
    <5>枚舉所有的名稱

foreach(string temp in Enum.GetNames(typeof(TimeOfDay)))
            lbNames.Text+=temp;
  

枚舉和常量



  優(yōu)先考慮枚舉。

  在C#中,枚舉的真正強(qiáng)大之處是它們?cè)诤笈_(tái)會(huì)實(shí)例化為派生于基類System.Enum的結(jié)構(gòu)。這表示可以對(duì)它們調(diào)用方法,執(zhí)行有用的任務(wù)。注意因?yàn)?NET Framework的執(zhí)行方式,在語法上把枚舉當(dāng)做結(jié)構(gòu)是不會(huì)有性能損失的。實(shí)際上,一旦代碼編譯好,枚舉就成為基本類型,與int和float類似。

  但是在實(shí)際應(yīng)用中,你也許會(huì)發(fā)現(xiàn),我們經(jīng)常用英語定義枚舉類型,因?yàn)殚_發(fā)工具本來就是英文開發(fā)的,美國人用起來,就直接能夠明白枚舉類型的含義。其實(shí),我們?cè)陂_發(fā)的時(shí)候就多了一步操作,需要對(duì)枚舉類型進(jìn)行翻譯。沒辦法,誰讓編程語言是英語寫的,如果是漢語寫的,那我們也就不用翻譯了,用起枚舉變得很方便了。舉個(gè)簡單的例子,TimeOfDay.Morning一看到Morning,美國人就知道是上午,但是對(duì)于中國的使用者來說,可能有很多人就看不懂,這就需要我們進(jìn)行翻譯、解釋,就向上面的getTimeOfDay()的方法,其實(shí)就是做了翻譯工作。所以,在使用枚舉的時(shí)候,感覺到并不是很方便,有的時(shí)候我們還是比較樂意創(chuàng)建常量,然后在類中,聲明一個(gè)集合來容納常量和其意義。

  使用常量定義:這種方法固然可行,但是不能保證傳入的參數(shù)day就是實(shí)際限定的。



using System;
using System.Collections.Generic;

public class TimesOfDay
{
    public const int Morning = 0;
    public const int Afternoon = 1;
    public const int Evening = 2;
    public static Dictionary<int, string> list;
    /// <summary>
    /// 獲得星期幾
    /// </summary>
    /// <param name="day"></param>
    /// <returns></returns>
    public static string getTimeNameOfDay(int time)
    {
        if (list == null || list.Count <= 0)
        {
            list = new Dictionary<int, string>();
            list.Add(Morning, "上午");
            list.Add(Afternoon, "下午");
            list.Add(Evening, "晚上");
        }

        return list[time];
    }
}










希望能夠找到一種比較好的方法,將枚舉轉(zhuǎn)為我們想要的集合。搜尋了半天終于找到了一些線索。通過反射,得到針對(duì)某一枚舉類型的描述。

枚舉的定義中加入描述

using System;
using System.ComponentModel;

public enum TimeOfDay
{
    [Description("上午")]
    Moning,
    [Description("下午")]
    Afternoon,
    [Description("晚上")]
    Evening,
};


  獲得值和表述的鍵值對(duì)

        /// <summary>
        /// 從枚舉類型和它的特性讀出并返回一個(gè)鍵值對(duì)
        /// </summary>
        /// <param name="enumType">Type,該參數(shù)的格式為typeof(需要讀的枚舉類型)</param>
        /// <returns>鍵值對(duì)</returns>
        public static NameValueCollection GetNVCFromEnumValue(Type enumType)
        {
            NameValueCollection nvc = new NameValueCollection();
            Type typeDescription = typeof(DescriptionAttribute);
            System.Reflection.FieldInfo[] fields = enumType.GetFields();
            string strText = string.Empty;
            string strValue = string.Empty;
            foreach (FieldInfo field in fields)
            {
                if (field.FieldType.IsEnum)
                {
                    strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString();
                    object[] arr = field.GetCustomAttributes(typeDescription, true);
                    if (arr.Length > 0)
                    {
                        DescriptionAttribute aa = (DescriptionAttribute)arr[0];
                        strText = aa.Description;
                    }
                    else
                    {
                        strText = field.Name;
                    }
                    nvc.Add(strText, strValue);
                }
            }
            return nvc;
        }




.NET中Flags枚舉的使用

 .NET中的枚舉我們一般有兩種用法,一是表示唯一的元素序列,例如一周里的各天;還有就是用來表示多種復(fù)合的狀態(tài)。這個(gè)時(shí)候一般需要為枚舉加上[Flags]特性標(biāo)記為位域,例如:




[Flags]
enum Styles{
ShowBorder = 1,         //是否顯示邊框
ShowCaption = 2,        //是否顯示標(biāo)題
ShowToolbox = 4         //是否顯示工具箱
}




  這樣我們就可以用"或"運(yùn)算符組合多個(gè)狀態(tài),例如:





myControl.Style = Styles.ShowBorder | Styles.ShowCaption;  




  這時(shí)myControl.Style枚舉的值將變成 1+2=3,它的ToString()將變成"Styles.ShowBorder , Styles.ShowCaption"
這里我們可以解釋為什么第三個(gè)值ShowToolbox可以為4,5..而不能為3。也就是說它的值不應(yīng)該是前幾項(xiàng)值的復(fù)合值。有一個(gè)比較簡單的方法就是用2的n次方來依次為每一項(xiàng)賦值,例如 1,2,4,8,16,32,64.....

現(xiàn)在舉個(gè)常見的Flags應(yīng)用例子。例如一個(gè)簡單的權(quán)限系統(tǒng),有"Admin"和"User"兩種角色,我們可以在表中放一個(gè) varchar()字段,以文本形式存放權(quán)限字"Admin,User"。但是用Flags型枚舉的話,我們就可以直接將 Roles.Admin | Roles.User 的值放在一個(gè)int字段里。

以下是關(guān)于枚舉的一些常見操作:
將枚舉的值變回枚舉對(duì)象:
Styles style = (Styles) Enum.Parse(typeof(Styles), 4 );    // -> style = Styles.Toolbox;
  檢查枚舉是否包含某個(gè)元素:
bool hasFlag = ((style & Styles.ShowBorder) != 0);

其實(shí)我們還會(huì)碰到一種情況,就是需要從組合狀態(tài)中去掉一個(gè)元素。用"^"運(yùn)算符可以做到:





Styles style = Styles.ShowBorder | Styles.ShowCaption;
style = style ^ Styles.ShowBorder;





  這個(gè)時(shí)候style的值就會(huì)變成 Styles.ShowCaption

但這里有一個(gè)很嚴(yán)重的問題(偶現(xiàn)在才發(fā)現(xiàn))
我們這個(gè)時(shí)候再執(zhí)行一次
style = style ^ Styles.ShowBorder;
按照我們的設(shè)想,這個(gè)時(shí)候 style 的值是 Styles.ShowCaption,不包含 Styles.ShowBorder,所以我們就算去掉這個(gè)元素,style應(yīng)該還是不會(huì)變。但實(shí)際的 style 的值卻又變成了 Styles.ShowBorder | Styles.ShowCaption !! 再執(zhí)行一遍,又會(huì)去掉這個(gè)元素,周而復(fù)始。
當(dāng)然我們可以在去掉某個(gè)元素前做一番檢查,如果枚舉包含這個(gè)元素,再去掉它:





if ((style & Styles.ShowBorder) != 0){
style = style ^ Styles.ShowBorder;
}





  不知道有沒有其它方法可以方便地從Flags枚舉狀態(tài)中去掉一個(gè)元素。。

  Thanks to mobilebilly:
style = style & (~Styles.ShowBorder) 可以方便去掉一個(gè)元素。



好好利用枚舉

      這段時(shí)間手里有個(gè)有關(guān)訂單的項(xiàng)目,訂單一般有個(gè)狀態(tài)的,以前很多要時(shí)候都會(huì)想到訂單的狀態(tài)就那幾個(gè)種,就把它寫死吧,不用一個(gè)數(shù)據(jù)庫表了,太浪費(fèi)資源了,但寫死了用一個(gè)數(shù)字來代表一種訂單狀態(tài),這樣在編碼時(shí)還要記得什么數(shù)字代碼什么狀態(tài),如果不小心把它寫錯(cuò)了,會(huì)導(dǎo)致數(shù)據(jù)出錯(cuò)。
      后來想到.NET有個(gè)枚舉,這么好的東西為何不用上來呢,這不但可以方便以后的代碼維護(hù),也方便編碼。

public enum OrderState
{
    /// <summary>
    /// 無效狀態(tài)
    /// </summary>
    Invalid = 0,
    /// <summary>
    /// 客戶詢價(jià)
    /// </summary>
    CustomerQuery = 1,
    /// <summary>
    /// 客戶落單
    /// </summary>
    CustomerOrdered = 2,
    /// <summary>
    /// 客戶付款
    /// </summary>
    ReceiverCustomerPayment = 4,
    /// <summary>
    /// 向供貨商訂貨
    /// </summary>
    SupplierOrdered = 8,
    /// <summary>
    /// 供貨商確認(rèn)貨期
    /// </summary>
    SupplierOrderTerm = 16,
    /// <summary>
    /// 收到貨品
    /// </summary>
    RecieverGoods = 32,
    /// <summary>
    /// 客戶取消訂單
    /// </summary>
    CustomerCanceled = 64,
    /// <summary>
    /// 供貨商取消訂單
    /// </summary>
    SupplierCancelded = 128
}
但要從UI層看這些狀態(tài)怎么處理呢?
利用switch case

public static string GetOrderStateString(OrderState state)
    {
        switch (state)
        {
            case OrderState.Invalid:
                return "無效值";
            case OrderState.CustomerOrdered:
                return "客戶下單";
            case OrderState.CustomerCanceled:
                return "客戶取消訂單";
            case OrderState.CustomerQuery:
                return "客戶詢價(jià)";
            case OrderState.ReceiverCustomerPayment:
                return "客戶已付款";
            case OrderState.RecieverGoods:
                return "訂單到貨";
            case OrderState.SupplierCancelded:
                return "供貨商取消";
            case OrderState.SupplierOrdered:
                return "已向供貨商訂貨";
            case OrderState.SupplierOrderTerm:
                return "供貨商確認(rèn)貨期";
        }
        return "";
    }


如果以后還有更多的訂單狀態(tài)就修改這個(gè)枚舉和一個(gè)方法就行了,這么方便的東西為何就不用到我的程序中呢,我們?cè)诰幋a中,要想盡方法使代碼簡單、易用、易維護(hù)。
枚舉中有兩個(gè)很實(shí)用的方法
1、GetHashCode()   //返回該實(shí)例的值的哈希代碼
2、ToString()           //將此實(shí)例的值轉(zhuǎn)換為其等效的字符串表示

這兩個(gè)方法在編碼的時(shí)候會(huì)用到,GetHashCode()這個(gè)方法使用機(jī)會(huì)會(huì)更多。
有前枚舉的使用,我得出以上一點(diǎn)心得,與大家共享一下。



本文來自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/gulijiang2008/archive/2009/12/23/5061442.aspx
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 南澳县| 朝阳市| 孟村| 汶上县| 那曲县| 河西区| 平远县| 吴桥县| 南阳市| 砚山县| 德江县| 乐亭县| 临洮县| 云龙县| 金华市| 启东市| 鹿泉市| 万年县| 尖扎县| 德化县| 嘉黎县| 九龙城区| 永丰县| 屏山县| 舟曲县| 枞阳县| 潞西市| 鹿邑县| 青神县| 乐东| 右玉县| 遵义县| 宿松县| 九龙县| 福清市| 南木林县| 台南市| 南木林县| 定襄县| 肇州县| 佛学|