到目前為止,介紹的都是c#提供的簡單變數型別。還有3個略複雜(但非常有用)的變數,如下所示:
*列舉*結構
*陣列今天主講列舉,每種型別(除了string外)都有明確的取值範圍。誠然,有些型別(如double)的取值範圍非常大,可以看作是連續的,但其中的數值總是固定的。最簡單的示例是bool型別,它只有true或false。
有時候,我們希望變數提取的是乙個固定集合中的值。例如,orientation型別可以儲存north,south,east或west中的乙個值。此時,就可以使用列舉型別。列舉就可以完成這個orientation型別的任務:它們允許定義乙個型別,其中包含提供的限定值集合中的乙個值。
所以,需要建立自己的列舉型別orientation,它可以從上述的4個值中提取乙個值。注意這是乙個附加的步驟——不是僅僅宣告乙個給定型別的變數,而是宣告和描述乙個使用者定義的型別,再宣告這個新型別的變數。
列舉可以使用enum關鍵字來定義,如下所示:
enum typename
value1,
value2,
value3,
valuen
接著宣告這個新型別的變數:
typename varname;
並賦值:
varname = typename.value;
列舉使用乙個基本型別來儲存。列舉型別可以提取的每個值都儲存為該基本型別的乙個值,在預設情況下,該型別為int。在列舉宣告中新增型別,就可以指定其他基本型別:
enum typename : underlyingtype
value1,
value2,
value3,
valuen
列舉的基本型別可以是byte,sbyte,short,ushort,int,uint,long和ulong。
在預設情況下,每個值都會根據定義的順序(從0開始),自動賦給對應的基本型別值。這意味著value1的值是0,value2的值是1,value3的值是2等。可以重寫這個賦值過程:使用=運算子,並制定每個列舉的實際值:
enum typename : underlyingtype
value1 = actualval1,
value2 = actualval2,
value3 = actualval3,
valuen = actualvaln,
另外,還可以使用乙個值作為另乙個列舉的基礎值,為多個列舉制定相同的值:
enum typename :underlyingtype
value1 = actualvall,
value2 = value1,
value3,
valuen = actualvaln
沒有賦值的任何值都會獲得乙個初始值,這裡使用的值是從此最後乙個明確宣告的值大1開始的序列。例如,在上面的**中,value3的值是value + 1。
注意這可能會產生預料不到的問題,在乙個定義如value2 = value1後指定的值可能與其他值相同。例如,在下面的**中,value4的值與value2相同。
enum typename : underlyingtype
value1 = actualval1,
value2,
value3 = vale1,
value4,
valuen = actualvaln
當然,如果這正是希望的結果,則**就是正確的。
還要注意,以迂迴方式賦值可能會產生錯誤,例如:
enum typename : underlyingtype
value1 = value2,
value2 = value1
下面看乙個例子,其**定義了乙個列舉orientation,然後演示它的用法。
using
system;
using
system.collections.generic;
using
system.text;
namespace
enumerate
class
program
", mydirection);
console.readkey();}}
}當然你也可以修改部分**,**如下:
byte
directionbyte;
string
directionstring;
orientation mydirection
=orientation.north;
console.writeline(
"mydirection =
", mydirection);
directionbyte =(
byte
)mydirection;
directionstring
=convert.tostring(mydirection);
console.writeline(
"byte equivalent =
", directionbyte);
console.writeline(
"string equivalent =
", directionstring);
console.readkey();
示例的說明
這段**定義並使用了乙個列舉型別orientation。首先要注意的是,型別定義**放在命名空間中,而沒有與其他**放在一起,是因為在執行期間,定義**並不是像執行應用程式中的**那樣一行一行的執行。應用程式是從已經習慣的位置開始執行的,並可以訪問新型別,因為它屬於同乙個命名空間。
這個例子的第乙個迭代演示了建立新型別的變數,給它賦值以及把它輸出到螢幕上的基本方法。
接著修改**的部分,把列舉值轉換為其他型別。注意這裡必須使用顯示轉換。即使orientation的基本型別是byte,仍必須使用(byte)資料型別轉換,把mydirection的值轉換為byte型別。
directionbyte = (byte)mydirection;
如果把byte型別轉換為orientation,也需要進行顯示轉換,例如,可以使用下述**把byte變數mybyte轉換為orientation,並把這個值賦給mydirection:
mydirection = (orientation)mybyte;
這裡必須小心,因為並不是所有byte型別變數的值都可以對映為已定義的orientation值。orientation型別可以儲存其他byte值,所以不會直接產生乙個錯誤,但會在應用程式的後面違反邏輯。
要獲得列舉的字串值,可以使用convert.tostring():
directionstring = convert.tostring(mydirection);
使用(string)資料型別轉換是不行的,因為需要進行的處理並不僅僅是把儲存在列舉變數中的資料放在string變數中,而是更複雜一些。
另外,還可以使用變數本身的tostring()命令。下面的**與使用convert.tostring()的效果相同:
directionstring = mydirection.tostring();
也可以把string轉換為列舉值,但其語法略複雜一些。有乙個特定的命令用於這種型別的轉換,即enum.parse(),其使用方式如下:
(enumerationtype)enum.parse(typeof(enumerationtype),enumerationvaluestring);
它使用了另乙個運算子typeof,可以得到運算元的型別。對orientation型別使用這個命令,如下所示:
string mystring = "north";
orientation mydirection = (orientation)enum.parse(typeof(orientation),mystring);
當然,並不是所有的字串值都會對映為乙個orientation值。如果乙個值不能對映為列舉值中的乙個,就會產生錯誤。與c#中的其他值一樣,這些值是區分大小寫的,否則就會產生錯誤。
變數的更多內容 型別轉換 顯式轉換
顧名思義,在明確要求編譯器把數值從一種資料型別轉換位另一種資料型別時,就是在執行顯式轉換。因此,這需要編寫額外的 的格式將隨著轉換方法的不同而不同。在學習顯式轉換 前,先看看如果不新增任何顯式轉換 會發生什麼情況。byte destinationvar short sourcevar 7 desti...
學習C (五)變數的更多內容
型別轉換即把值從一種型別轉換為另外一種型別。闡述一些型別的變數 列舉 一種變數型別,使用者定義了一組可能的離散值,這些值可用人們能理解的方式使用 結構 一種合成的變數型別,由使用者定義的一組其他變數型別組成。陣列 包含一種型別的多個變數,允許以索引方式訪問各個值。無論是什麼型別,所有資料都是一系列的...
複雜的變數型別 列舉,結構,陣列
1.列舉 允許定義乙個型別,提取我們提供的限定值集合中的乙個值 如 orientation型別可以儲存north,south,east 或 west 中的乙個值.此時就可以使用列舉型別,建立自己的列舉型別orientation,他可以從上述四個值中提取乙個值.注意這是乙個附加的步驟 不是只宣告乙個給...