您好,登錄后才能下訂單哦!
這篇文章主要講解了“C#枚舉賦值的方法是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C#枚舉賦值的方法是什么”吧!
Q:我留意到Code #02中的
.field public static literal Aligment Center = int32(0x00000001)
該語句明顯是整數賦值,這是否說明C#枚舉類型實質上是整數類型?
A:這說明枚舉類型與整數類型的確有一定的關系。事實上,每一個枚舉類型都有與之相對應的整數類型,我們稱該整數類型為底層類型(underlying type),默認的情況下使用,.NET使用System.Int32。當然,你可以手動將其指定為其他的整數類型:
// Code #09 public enum Alignment : byte { Left, Center, Right }
注意,能被指定為枚舉的底層類型的只能是如下所列的整數類型:byte, sbyte, short, ushort, int, uint, long, ulong。
--------------------------------------------------------------------------------
Q:為何我們需要指定枚舉類型的底層類型?
A:你完全可以讓它接受默認的底層類型。請留意Code #08,你完全找不到“Center”這個字眼,然而在C#代碼中,它卻是存在的,為什么呢?這是因為代碼在編譯的時候,編譯器把枚舉類型轉換為與之對應的底層類型的數值來處理。Code #08的L_0000實際上就是把類型為System.Int32的數值1推入堆棧,而不是把“Center”推入堆棧。事實上,底層類型說明了如何為枚舉類型分配空間,不同的底層類型所占用的資源不同,大概當你在受限系統上進行開發的話,你就可能需要注意一下了。
--------------------------------------------------------------------------------
C#枚舉的賦值
Q:枚舉成員的值是怎樣規定的?
A:如果你沒有手動指定成員的值的話,從上往下看,各成員的值為:0, 1, 2, ...。說罷了,就是一個非負整數等差數列,其初值為0,步長為1。例如:
// Code #10 public enum Alignment { Left, // 0 Center, // 1 Right // 2 }
--------------------------------------------------------------------------------
Q:如果我有手動指定某些成員的值呢?
A:那么被賦值的成員的值就是你所指定的值。當然,無論你是否手動指定枚舉成員的值,遞增步長都不會變,總是為1。為了測試你是否理解,請說出下面枚舉個成員的值以及你的判斷理由(請用人腦而不是電腦來運行以下代碼):
// Code #11 public enum DriveType : sbyte { CDRom, Fixed = -2, Network, NoRootDirectory = -1, Ram, Removable = Network * NoRootDirectory, Unknown }
--------------------------------------------------------------------------------
Q:我們如何獲取枚舉成員的值,無論成員是否被手動賦值?
A:你可以使用System.Enum的
public static Array GetValues(Type enumType);
該方法返回一個包含所有枚舉成員的數組:
// Code #12 // See Code #01 for Alignment. public static void Main() { Alignment[] alignments = (Alignment[])Enum.GetValues(typeof(Alignment)); Console.WriteLine("Wanna see the values of Alignment's menbers?"); foreach (Alignment a in alignments) Console.WriteLine("{0:G} = {0:D}", a); } // Output: // Wanna see the values of Alignment's menbers? // Left = 0 // Center = 1 // Right = 2
--------------------------------------------------------------------------------
Q:如果我只需要其中某些枚舉成員的值呢?
A:那么你可以把枚舉轉換為IConvertible接口,再調用對應的方法:
// Code #12 // See Code #01 for Alignment. public static void Main() { IConvertible ic = (IConvertible)Alignment.Center; int i = ic.ToInt32(null); Console.WriteLine("The value of Alignment.Center is {0}.", i); } // Output: // The value of Alignment.Center is 1.
--------------------------------------------------------------------------------
Q:為什么需要手動指定枚舉成員的值?
A:一般情況下,使用默認的賦值規則就足夠了,但某些情況下,為枚舉成員指定一個與實際情況(模型)相符的值可能更有意義,這要視你具體所建的模型而定。
還是讓我們來一個實際的例子:
// Code #13 public enum CustomerKind { Normal = 90, Vip = 80, SuperVip = 70, InActive = 100 } public class Customer { public readonly CustomerKind Kind; private double m_Payment; public double Payment { return m_Payment * (int)Kind / 100; } // Code here }
我為枚舉CustomerKind的每個成員都賦了一個特定的值,該值其實就是顧客購物折扣百分率。而在Customer類中,Payment屬性就通過強類型轉換來獲取枚舉成員的值(也就是購物折扣率),并用于貨款計算。從這里可以看出,獲取枚舉成員的值還可以通過強類型轉換方式。
--------------------------------------------------------------------------------
Q:既然枚舉類型可以強制轉換為整數,那么整數是否也可以強制轉換為枚舉類型?
A:答案是肯定的。
// Code #14 // See Code #01 for Alignment. Alignment a = (Alignment)1;
但這種機制可能使你遇到一些麻煩:
// Code #15 // See Code #01 for Alignment. class Program { static void Main() { Foo((Alignment)12345); } static void Foo(Alignment a) { // Code here } }
你無法避免有人進行這樣的惡作劇!!
--------------------------------------------------------------------------------
Q:那么是否有辦法對付這些惡作劇的人?
A:Sure!我們總不能假設人人都那么守規矩,所以,我們需要System.Enum的
public static bool IsDefined(Type enumType, object value);
現在我們把Code #15的Foo方法改進一下:
// Code #16 // See Code #01 for Alignment. static void Foo(Alignment a) { if (!Enum.IsDefined(typeof(Alignment), a)) throw new ArgumentException("DO NOT MAKE MISCHIEF!"); // Code here }
這樣,惡作劇的人將會收到一個警告(異常消息)。當然,我們不排除有人是由于一時大意才造成這樣的“惡作劇”,那么IsDefined方法同樣可以幫助你處理好這些情況。
--------------------------------------------------------------------------------
Q:我認為我們還可以使用條件判斷語句來處理這種情況:
// Code #17 // See Code #01 for Alignment. static void Foo(Alignment a) { if (a != Alignment.Left && a != Alignment.Center && a != Alignment.Right) throw new ArgumentException("DO NOT MAKE MISCHIEF!"); // Code here }
或者
// Code #18 // See Code #01 for Alignment. static void Foo(Alignment a) { switch(a) { case Alignment.Left: Console.WriteLine("Cool~"); break; case Alignment.Center: Console.WriteLine("Well~"); break; case Alignment.Right: Console.WriteLine("Good~"); break; default: Console.WriteLine("DO NOT MAKE MISCHIEF!"); break; } }
A:你絕對可以這樣做!事實上,如果你處于以下情況之一的話:
1. Alignment枚舉代碼不會被修改
2. 你不希望使用Alignment枚舉新增的特性
那么我會推薦使用你的處理方式。而且,你還可以為自己的代碼定義一個這樣的方法:
// Code #19 // See Code #01 for Alignment. public static bool IsAlignment(Alignment a) { switch(a) { case Alignment.Left: return true; case Alignment.Center: return true; case Alignment.Right: return true; default: return false; } }
這個方法比起IsDefine方法高效多了。
感謝各位的閱讀,以上就是“C#枚舉賦值的方法是什么”的內容了,經過本文的學習后,相信大家對C#枚舉賦值的方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。