天天看點

關于c# 枚舉 enum 的學習

從長遠來看,建立枚舉可以節省大量的時間,減少許多麻煩。使用枚舉比使用無格式的整數至少有如下三個優勢:

●       枚舉可以使代碼更易于維護,有助于確定給變量指定合法的、期望的值。

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

●       枚舉使代碼更易于鍵入。在給枚舉類型的執行個體指派時,vs.net ide會通過intellisense彈出一個包含可接受值的清單框,減少了按鍵次數,并能夠讓我們回憶起可能的值。

public enum filestates{begin=1,pause=2,rollback=3,success=4};

枚舉類型都是值類型。system.enum是一個抽象類(abstract class),所有枚舉類型都直接繼承自它,當然也同時繼承了它的所有成員。所有的值類型都是system.valuetype的後代,枚舉類型也不例外,枚舉類型直接繼承自system.enum,而system.enum卻又直接繼承自system.valuetype的,是以,枚舉類型也是system.valuetype的後代。

值類型都是system.valuetype的後代”,但system.valuetype的後代不全是值類型,system.enum就是唯一的特例!在system.valuetype的所有後代中,除了system.enum之外其它都是值類型。事實上,我們可以在.net的源代碼中找到system.enum的聲明:

關于c# 枚舉 enum 的學習

public abstract class enum : valuetype, icomparable, iformattable, iconvertible

1. 所有枚舉類型(enum type)都是值類型。

2. system.enum和system.valuetype本身是引用類型。

3. 枚舉類型(enum type)都是隐式的直接繼承自system.enum,并且這種繼承關系隻能由編譯器自動展開。但system.enum本身不是枚舉類型(enum type)。

4. system.enum是一個特例,它直接繼承自system.valuetype,但本身卻是一個引用類型。

a:枚舉類型可以被裝箱成system.enum、system.valuetype、system.object或者system.iconvertible、system.iformattable、system.icomparable。

注意:在.net 1.1上,枚舉類型隻能被裝箱到system.enum、system.valuetype、system.object;而在.net 2.0上,枚舉類型還能被裝箱到system.enum所實作的三個接口:system.iconvertible、system.icomparable、system.iformattable。對應的裝箱操作既可以為隐式的也可以是顯式的。

枚舉類型與整數類型有一定的關系。事實上,每一個枚舉類型都有與之相對應的整數類型,我們稱該整數類型為底層類型(underlying type),預設的情況下使用,.net使用system.int32。當然,你可以手動将其指定為其他的整數類型:

能被指定為枚舉的底層類型的隻能是如下所列的整數類型:byte, sbyte, short, ushort, int, uint, long, ulong。

如果你沒有手動指定成員的值的話,從上往下看,各成員的值為:0, 1, 2, ...。說罷了,就是一個非負整數等差數列,其初值為0,步長為1。例如:

 public enum alignment

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

{

關于c# 枚舉 enum 的學習

      left,    // 0

關于c# 枚舉 enum 的學習

      center,    // 1

關于c# 枚舉 enum 的學習

      right    // 2

關于c# 枚舉 enum 的學習

  }

那麼被指派的成員的值就是你所指定的值。當然,無論你是否手動指定枚舉成員的值,遞增步長都不會變,總是為1。為了測試你是否了解,請說出下面枚舉個成員的值以及你的判斷理由(請用人腦而不是電腦來運作以下代碼):

public enum drivetype : sbyte

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      cdrom,

關于c# 枚舉 enum 的學習

      fixed = -2,

關于c# 枚舉 enum 的學習

      network,

關于c# 枚舉 enum 的學習

      norootdirectory = -1,

關于c# 枚舉 enum 的學習

      ram,

關于c# 枚舉 enum 的學習

      removable = network * norootdirectory,

關于c# 枚舉 enum 的學習

      unknown

關于c# 枚舉 enum 的學習

public enum customerkind

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      normal = 90,

關于c# 枚舉 enum 的學習

      vip = 80,

關于c# 枚舉 enum 的學習

      supervip = 70,

關于c# 枚舉 enum 的學習

      inactive = 100

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

  public class customer

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      public readonly customerkind kind;

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      private double m_payment;

關于c# 枚舉 enum 的學習

      public double payment

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

          return m_payment * (int)kind / 100;

關于c# 枚舉 enum 的學習

      }

為枚舉customerkind的每個成員都賦了一個特定的值,該值其實就是顧客購物折扣百分率。而在customer類中,payment屬性就通過強類型轉換來擷取枚舉成員的值(也就是購物折扣率),并用于貨款計算。從這裡可以看出,擷取枚舉成員的值還可以通過強類型轉換方式。

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      // code here

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

枚舉類型可以強制轉換為整數,整數也可以強制轉換為枚舉類型

alignment a = (alignment)1;但這種機制可能使你遇到一些麻煩

public static bool isalignment(alignment a)

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      switch(a)

       {

    case alignment.left:

    case alignment.center:

    case alignment.right:

      return true;

    default:

      return false;

      }

關于c# 枚舉 enum 的學習

枚舉類型轉換(解析)成字元串類型

最簡單的方法就是使用system.enum的public override string tostring();  或者把枚舉類型轉換為iconvertible接口,再調用該接口的string tostring(iformatprovider provider);

 static void main()

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      alignment a = alignment.right;

關于c# 枚舉 enum 的學習

      console.writeline("alignment is {0}.", a.tostring());

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      fontstyle fs = fontstyle.bold | fontstyle.underline;

關于c# 枚舉 enum 的學習

      console.writeline("fontstyle is {0}.", fs.tostring());

關于c# 枚舉 enum 的學習

手動指定格式參數:console.writeline("alignment is {0}.", a.tostring("d"));

一個表示枚舉成員的字元串,如何将其解析為對應枚舉類型:

這時你就需要system.enum的public static object parse(  type enumtype, string value,  bool ignorecase  );

static void main()

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      string name = "right";

關于c# 枚舉 enum 的學習

      alignment a = (alignment)enum.parse(typeof(alignment), name, false);

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      console.writeline(a.tostring());

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      string names = "bold, italic, underline";

關于c# 枚舉 enum 的學習

      fontstyle fs = (fontstyle)enum.parse(typeof(fontstyle), names, false);

關于c# 枚舉 enum 的學習
關于c# 枚舉 enum 的學習

      console.writeline(fs.tostring());

關于c# 枚舉 enum 的學習

不應該使用枚舉的情況:

關于c# 枚舉 enum 的學習

枚舉類型表達了一種穩定的分類标準。當你檢視.net framework bcl中的枚舉類型,你會發現它們幾乎沒有任何改變的可能或者趨勢,表現出一種穩定性。是以,當你所要表達的分類标準也同樣具備這種穩定性時,你就可以考慮枚舉類型了。那麼什麼情況下不使用枚舉呢?一般說來,當分類标準不閉合時——即新的子分類随時有可能産生或者現有子分類随時有可能被替換——你就應該考慮使用其他的方式來表達了.

繼續閱讀