細說C 中的列舉 轉換 標誌和屬性

2022-09-26 02:33:11 字數 3539 閱讀 1985

列舉是 c# 中最有意思的一部分,大部分開發人員只了解其中的一小部分,甚至網上絕大多數的教程也只講解了列舉的一部分。那麼,我將通過這篇文章向大家具體講解一下列舉的知識。我將從大家都了解的部分開始講解,然後再講解大家所不知道的或者了解很少的部分。

零、基礎知識

列舉是由開發人員宣告的一種 值型別 ,它在編譯時就宣告了一種 具名常量值 。使用列舉可以使我們的**簡單易讀,我們先來看一下兩個**段:

// **段 1

void method(int country) }

// **段 2

void method(country country)

}從上面的兩個**段我們可以看到兩者有明顯的區別。第一段**中的 case 值我們幾乎完全不知道代表了什麼是什麼意思,但是第二段**我們使用了列舉,通過 case 值馬上就可以知道所要表達的意思。同樣利用列舉值替代布林值也可以改善**的可讀性,例如我們要開發控制檯燈開啟關閉的程式,**可以這麼寫 lightoperating(true) ,但是這種**我們無法看出具體要幹什麼,現在我們將**改動一下 lightoperating(light.on) 。經過修改**就很容易看出所要表達的意思。

1.列舉定義與取值 定義列舉有兩種方式,分別是普通方式和自定義方式。不管使用哪種方式都需要用的關鍵字 enum 來標識這個型別為列舉型別,並且列舉值都是作為整數常量來實現的。下面我們就來看一下這兩種方式怎麼定義列舉的。普通方式是我們經常用到的,也是預設的方式。這種方式很簡單,**如下:

enum country

在上面的**段中我們定義了乙個國家列舉,第乙個列舉值對應的整數常量是 0 ,第二個列舉值對應的整數常量是 1 ,以此類推後面的列舉值分別對應的整數常量是 2 和 3 。但是在部分情況下我們需要自定義列舉值對應的整數常量,這個時候我們就需要用到自定義的方式。自定義方式又稱為為列舉值顯式賦值,它的方法如下所示:

enum country

我們在**中將第乙個列舉值對應的整數常量設定為了 3 ,這時第二個列舉值的整數常量就不是 1 了,而是 4 ,因為當列舉值沒有顯示賦值時,將會按照上乙個列舉值對應的整數值加 1 來作為自己本身對應的整數值。最後兩個列舉值因為顯式賦值了因此對應的整數值就是所賦值的數值。 列舉取值也很簡單,只需要 列舉名.列舉值 即可,例如 country.uk 。

tip:這裡我提幾點建議:

2.列舉的型別 到目前為止我們定義列舉型別使用的基礎型別 int 型別,但是列舉不僅僅可以使用 int 型別,還可以使用除了 char 型別之外的所有基礎型別。我們可以使用繼承語法來指定其他型別。

enum country:short

上面**中我們顯式定義了列舉所使用的基礎型別為 short 。這裡雖然使用了繼承語法但是並沒有建立繼承關係,所有的列舉基類都是 system.enum ,這些類都是密封類,無法從現有的列舉型別派生出新的成員。 對於列舉型別的變數,值不限於宣告中命名的值,因此值能轉換成基礎型別,那麼就能轉換為列舉型別。之所以這麼設計是因在以後的 api 中有很大的可能在不破換老版本的同時為列舉新增新的值。但是這其中也存在乙個缺陷,列舉允許在執行時分配未知的值,對於這一點我們在開發時需要考慮到。並且在後期向列舉中新增新的列舉值時應將其新增到所有列舉值的後面,或者顯示指定列舉值對應的數值,這樣才能避免因新增新值導致列舉型別中的列舉值對應的數值改變。

tip:在開發中我們應該盡量使用 int 作為列舉的基礎型別,除非因效能問題或互操作方面的考慮時才會考慮使用較小的型別。

一、列舉轉換

列舉轉換主要涉及到了列舉與列舉的轉換、列舉與數字和字串的轉換。

1.列舉之間轉換 首先我要說明的是在 c# 中不支援不同列舉陣列之間的直接轉換,所以如果想要實現不同列舉陣列之間的轉換我們可以利用 clr 寬鬆的賦值相容性這一特點來進行轉換,需要轉換的兩個列舉必須具有相同的基礎型別。同樣,我們通過乙個例子來看一下具體實現方法。

static void main(string args)

enum country

enum countryallname

在使用這種方法時有可能會出現意外的錯誤或結果,並且相關開發規範中並沒有說這種方式每次都起作用,因此我不建議這麼使用,除非在一些極端場景中。

2.列舉和字串之間轉換 列舉轉換為字串可以直接使用 tostring() 方法, 列舉值 tostring 後會直接輸出列舉值識別符號的字串形式,例如country.cn.tostring()得到的結果是字串 cn 。當然,你也可以利用 enum.getnames 和 enum.getname 方法來獲取。下面我簡單來講解一下這兩個方法的使用。

tip:字串向列舉轉換不可本地化,如果必須本地化,就必須是那些對上層使用者不可見的訊息。因此在實際開發中應該盡量避免列舉和字串之間的轉換。

3.列舉和數字之間轉換 列舉轉換為數字我們可以使用強轉,例如 (int)country.cn 返回結果是 0 。從數字轉換為列舉我們有兩種方法,一種是使用強轉,另一種是使用 enum 的靜態方發 toobject 。

4.注意 字串轉換為列舉和數字轉換為列舉都必須先進行判斷所要轉換的值是否包含在列舉中,判斷的方法也很簡單只需要呼叫 enum 的靜態方法 isdefined 即可,例如我要將 0 和 hk 轉換為列舉,**如下:

type type = typeof(coun程式設計客棧try);

if(enum.isdefined(type,0))

if(enum.isdefined(type,"hk"))

上述**中只有 0 會成功轉換為列舉值 cn ,因為 0 所對應的列舉值是 cn ,而 hk 並沒有在列舉中。

三、標誌與屬性

這一小節我們來講解一下標誌與屬性,標誌he和屬性屬於在開發中用的比較少,並且大部分程式設計師了解的也不多。

1.標誌 在開發中有時我們希望能對列舉進行組合使用來表示復合值,那麼這時我們就需要定義標誌列舉了,標誌列舉的名稱為複數形式,代表了乙個標誌的集合。一般我們會使用按位或操作符鏈結列舉值,使用 hasflags 方法或者按位與操作符來判斷特定的位是否存在。比較經典的標誌列舉是位於 system.io 命名空間中的 fileattributes 標誌列舉,它列出了檔案的所有屬性,比如唯讀、隱藏、所在磁碟等等,它所包含的所有列舉值皆可相互組合,例如乙個檔案既是隱藏檔案又是唯讀檔案。定義標誌列舉的方法如下:

[flags]

enum weekdays

在上面的**中你會發現乙個規律,每個列舉值對應的整數值都是 2的n次方,這是為什麼呢。在標誌列舉中要求多個列舉值相互組合後的結果不能包含在標誌列舉中,並且基於按位運算的特性可以很方便的使用位運算子來計算乙個列舉值是否包含了另外乙個列舉值,這在許可權系統中相當有用。

2.屬性 列舉值上同樣也可以使用屬性,例如我們需要列印輸出列舉值的中文名,我www.cppcns.com們就可以通過屬性的形式進行設定,首先我們需要定義乙個屬性:

public class enumchineseattribute : attribute

public string description

} } enum country

static void main(string args)

通過上面的**我們就能獲取到 cn 對應的中文名稱了,這段**並沒有進行進一步優化,在實際專案中必須進行封裝和優化。

四、小結

本文位址:

C 中的標誌列舉

標誌列舉在宣告列舉前加 flag 列舉值一般用2的n次方 1 2 4 8.不能 1 2 3 因為標誌每組可以自由組合 1 2 3 就衝突了 下面將其十進位制轉化成為二進位制說明就可以明白點00001 1 00010 2 00100 4 01000 8 10000 16 高富帥白 00001 0001...

細說CSS中的display屬性

相信大部分奮戰在前端的,尤其在前端攻城的過程中,有一種越陷越深的感覺,不錯,一如前端深似海,從此妹子是浮雲啊,前端上手容易,深入難啊!下面我就css中的display屬性講下我自己所積累的,與大家共享下,大神勿噴,我只是路過的。css中display屬性在w3c教程上有簡要說明 當然我是覺得講的不夠...

c 中列舉和int之間的相互轉換

把列舉轉換成int就不用說了,列舉可以預設轉換為int,或者來乙個int強制轉換就ok了,比如 int myenum,但是反過來怎麼把乙個int轉換成乙個已知的列舉型別呢?比如1enumweekday,如何把2轉換成enumweekday.星期一呢?可以這樣啦 1enum.getname typeo...