1. 程式人生 > >解讀經典《C#高級編程》第七版 Page45-50.核心C#.Chapter2

解讀經典《C#高級編程》第七版 Page45-50.核心C#.Chapter2

註釋 關註 方便 -s 控制 studio ref 一個 效果

原文:解讀經典《C#高級編程》第七版 Page45-50.核心C#.Chapter2

前言

本篇講述枚舉和名稱空間。

01

枚舉

首先需要明確枚舉的概念:枚舉是用戶定義的整數類型。使用枚舉的目標是,使用一組容易記憶的名稱,來使得代碼更容易編寫和維護。

我們對比枚舉的定義和類的定義,會發現它們有像的地方,有不像的地方,這不同之處體現了枚舉的特性。我們按下圖舉例:

技術分享圖片

  1. C#中,一般習慣於一個文件定義一個類。而一個項目中可能有大量枚舉,一般建議將多個枚舉定義在一個文件中。
  2. 很多書中對於枚舉只有一個稱謂“枚舉”,但是,如上圖,到底是OrgType1是枚舉,還是Vendor是枚舉?實際上準確的說,OrgType1是枚舉,Vendor是枚舉值,或者叫枚舉成員。枚舉的枚舉成員和類的成員本質上是一樣的,都可以通過反射獲得成員的定義。枚舉值本質是System.Enum,是一個結構(struct)。
  3. 枚舉值可以強制指定,比如OrgType2。不指定時默認從0開始計數,比如OrgType1。OrgType1和OrgType2的枚舉值是一樣的,都是0和1。而OrgType3的枚舉值是100和101。枚舉值也就可以強制轉換成int

int value = (int)OrgType1.Vendor;

枚舉值被設計成簡單的整數,也是可以理解的,這使得在語言層面上枚舉的實現是簡約的,高效的。

  1. 枚舉的一個常用功能是將字符串轉換為枚舉值

var enumTemp = (OrgType1)Enum.Parse(typeof(OrgType1), “Vendor”);

從語言層面上看,枚舉定義的可謂非常完美。因為語言層面上,實際上我們只需要使用枚舉值(name)就行了,完全不需要關註枚舉值背後的int值。但是,當我們要將枚舉值序列化時,就出現問題了。

所謂序列化,也就是將枚舉數據存儲起來,一個常用的應用場景就是存儲到數據庫的某個字段中。在序列化時,枚舉特別適合表示數據庫表的狀態列,而存儲在數據庫中的狀態列有兩種,一種是字符串狀態值,一種是int狀態值,也可能兩者混合。比如:

技術分享圖片

技術分享圖片

我們發現,如果要把上述兩種狀態值都用枚舉表示,前者要使用枚舉值的表面量(name)來表示,後者要用int值來表示。比如以上兩種定義方式,對應的枚舉會定義為:

技術分享圖片

而它們的序列化和反序列化的方式,也各不相同:

技術分享圖片

針對不同的枚舉定義,需要使用不同的序列化和反序列化方式,會使編程變得繁瑣,有沒有將兩者統一的方法呢?我的做法是,使用特性。

技術分享圖片

技術分享圖片

如上圖,不管是什麽樣的枚舉定義方式,都使用特性EnumItemValue來描述。進行一定的封裝之後,枚舉的序列化和反序列化就統一為一種模式了:

bill.Status = EnumChangeBillStatus.Data1.GetEnumItemValue();

實現代碼:

技術分享圖片

02

名稱空間

名稱空間

名稱空間就是namespace定義。特別重要的是,名稱空間是一種邏輯組合,而不是物理組合。

類似的,在Visual Studio中,也有類似“名稱空間”或者“路徑”,分別屬於“邏輯組合”或者“物理組合”。

解決方案目錄:解決方案目錄屬於邏輯組合,它並不對應磁盤中的實際目錄,而只是解決方案文件中的一個邏輯位置定義。

項目中的目錄:項目中的目錄對應磁盤上實際的文件夾目錄,是一個物理位置。

技術分享圖片

名稱空間可以嵌套,比如下圖中,上面的嵌套聲明方式和下面的聲明方式,效果是等同的。不過我們一般不會用上面這種方式,而用下面的方式:

技術分享圖片

Using

引入類之前一般需要通過using引入類所在的名稱空間,從而方便類的引用。如:

using System;

using MJ = BL.Test.ConsoleTest.CSharp高級編程.枚舉;

如上的例子上,還用到了別名MJ。一般在碰到在不同的namespace下有兩個同名類時,會使用別名。訪問別名下的類,使用別名修飾符 ::

var value1 = (int)MJ.OrgType1.Vendor;

var value2 = (int)MJ::OrgType1.Vendor;

我發現,使用::和.都能訪問別名下的類,那為什麽C#要特別設計“別名修飾符”呢?暫時不能理解。

下一篇將完成第二章的解讀。會講一些細小的特性和功能:Main方法,控制臺,註釋,預處理指令,編程規範等。

覺得文章有意義的話,請動動手指,分享給朋友一起來共同學習進步。

歡迎關註本人微信公眾號,更及時的關註最新文章(每周三篇原創文章,以及多篇專題文章):

技術分享圖片

附文:

(轉)C# Enum,Int,String的互相轉換 枚舉轉換

[C#基語法]之C#命名空間(namespace)

上一篇:解讀經典《C#高級編程》第七版 Page38-45.核心C#.Chapter2

解讀經典《C#高級編程》第七版 Page45-50.核心C#.Chapter2