C# Notizen 5 創(chuàng)建枚舉類型和結(jié)構(gòu)

一、枚舉類型
枚舉類型也成為枚舉,它是一種創(chuàng)建數(shù)值類型的機(jī)制,這種值類型的可能取值是預(yù)定義的,而對(duì)于其中的每個(gè)可能取值,都有一個(gè)有意義的名稱。這看似簡(jiǎn)單,但實(shí)際上枚舉類型功能強(qiáng)大。通過定義一組有效值,而程序員能夠理解表層含義。這樣,代碼的含義將不言自明,也不再模糊。
要定義枚舉,必須在標(biāo)識(shí)符前面加上關(guān)鍵字enum,然后在枚舉體內(nèi)定義一組有效值,并用逗號(hào)分隔它們。用作值名稱的標(biāo)識(shí)符必須遵循的規(guī)則與變量標(biāo)識(shí)符相同。

ps:枚舉值
最后一個(gè)枚舉值后面的逗號(hào)是可選的,但最好不要省略,這樣以后添加枚舉值將更容易。

ps:多名稱值
可以有多個(gè)名稱對(duì)應(yīng)于同一個(gè)數(shù)值,這在有多個(gè)名稱表示同一個(gè)概念時(shí)很有用。為讓多個(gè)名稱對(duì)應(yīng)于同一個(gè)數(shù)值,只需添加新名稱,并將其設(shè)置成與另一個(gè)名稱相等,如下所示。

枚舉是一組只能為數(shù)值的命名常量,因此最好讓每個(gè)名稱對(duì)應(yīng)于不同的數(shù)值。定義枚舉時(shí),編譯器默認(rèn)將第一個(gè)枚舉值設(shè)置為整數(shù)零,其他值則依次加1。

ps:零值(zero value)
通常最好在枚舉中包含對(duì)應(yīng)于0的名稱None。

枚舉支持大多數(shù)可用于整數(shù)值的運(yùn)算符,但并非所有這些運(yùn)算符對(duì)枚舉來(lái)說(shuō)都有意義。對(duì)于枚舉,執(zhí)行得最多的操作是相等和不等測(cè)試。由于枚舉屬于值類型,因此也可聲明可以為null的枚舉。

ps:枚舉的底層類型
枚舉包含的所有值都必須是同一種數(shù)據(jù)類型的,這種數(shù)據(jù)類型稱為底層類型(underlying type)。默認(rèn)情況下,枚舉的底層類型為 int,但是也可以使用任何預(yù)定義的整數(shù)類型:byte、short、int、long、sbyte、ushort、uint和ulong。

1.1 位標(biāo)志枚舉
通過使用位標(biāo)志枚舉(flags enumeration),可組合其中的值。使用位標(biāo)志枚舉時(shí),可使用邏輯運(yùn)算OR創(chuàng)建新的組合值。
為讓位標(biāo)志枚舉的值能夠組合,所有值都必須是2的冪。這是因?yàn)榻M合多個(gè)值時(shí),必須能夠確定結(jié)果為哪個(gè)離散值。因此,定義位標(biāo)志枚舉時(shí),必須指定名稱對(duì)應(yīng)的值。

ps:Flags特性
常規(guī)枚舉和位標(biāo)志枚舉之間的另一個(gè)差別是,后者需要使用Flags特性,它指定有關(guān)枚舉的額外元數(shù)據(jù)。
Flags特性還改變了組合得到的枚舉值的字符串表示(方法ToString返回的結(jié)果)。
雖然并非必須使用Flags特性,但是強(qiáng)烈建議這樣做,因?yàn)橄蚓幾g器和其他程序員清晰地表明了你的意圖。
在簡(jiǎn)單枚舉中,可以讓名稱None或最常見的默認(rèn)名稱對(duì)應(yīng)于0,但是位標(biāo)志枚舉與此不同,它要求0對(duì)應(yīng)于名稱None,這個(gè)值意味著所有標(biāo)志都未設(shè)置。

二、結(jié)構(gòu)
在需要簡(jiǎn)單的用戶定義的類型時(shí),可將結(jié)構(gòu)作為類的輕量級(jí)替代品。結(jié)構(gòu)類似于類,可包含的成員類型與類相同,但是屬于值類型而不是引用類型。結(jié)構(gòu)與類的不同之處如下:

  • 接口不支持繼承。結(jié)構(gòu)隱式地繼承System.ValueType,而后者繼承System.Object。就像類一樣,結(jié)構(gòu)也可繼承接口
  • 結(jié)構(gòu)隱式地被密封,這意味著您不能繼承結(jié)構(gòu)
  • 結(jié)構(gòu)不能有析構(gòu)函數(shù),不能聲明默認(rèn)構(gòu)造函數(shù),也不能在結(jié)構(gòu)體內(nèi)初始化實(shí)例字段。如果結(jié)構(gòu)提供了構(gòu)造函數(shù),就必須在其中給所有字段賦值

ps:基類庫(kù)中的結(jié)構(gòu)
除 string 和 object 外,所有基本數(shù)據(jù)類型都被實(shí)現(xiàn)為結(jié)構(gòu)。.NET Framework提供了200多個(gè)公有結(jié)構(gòu),下面是一些常用的結(jié)構(gòu):
System.DateTime
System.DateTimeOffset
System.Guid
System.TimeSpan
System.Drawing.Color
System.Drawing.Point
System.Drawing.Rectangle
System.Drawing.Size

在C#中,結(jié)構(gòu)的聲明方法與類相同,只是需要使用關(guān)鍵字struct代替關(guān)鍵字class

2.1 方法
就像類可以定義方法一樣,結(jié)構(gòu)也可以。這些方法要么是靜態(tài)方法,要么是實(shí)例方法,但是結(jié)構(gòu)較常使用靜態(tài)共有方法和私有實(shí)例方法

運(yùn)算符重載
由于結(jié)構(gòu)是用戶定義的值類型,因此如果變量的類型為您定義的結(jié)構(gòu),就不能將大多數(shù)常見的運(yùn)算符用于它。這是一種重大缺陷,所幸的是,C #通過運(yùn)算符重載提供了一種解決這個(gè)問題的方式。
如果將運(yùn)算符視為名稱特殊的方法,那么運(yùn)算符重載就是一種特殊的方法重載。要聲明重載的運(yùn)算符,可定義一個(gè)public static方法,其名稱為關(guān)鍵字operator和要重載的運(yùn)算符的符號(hào)。另外,至少要有一個(gè)參數(shù)的類型與重載運(yùn)算符所屬的類型相同。下表列出了可重載的運(yùn)算符。

類別 運(yùn)算符
單目 + - ! ~ ++ true false
乘除 * / %
加減 + -
移位 << >>
關(guān)系 < > <= >=
邏輯 & 丨 ^
相等性 == !=

ps:語(yǔ)言互操作性
并非所有.NET 語(yǔ)言都支持運(yùn)算符重載,因此如果創(chuàng)建的類要在其他語(yǔ)言中使用,它們應(yīng)符合CLS,并提供與定義的重載運(yùn)算符對(duì)應(yīng)的替代品。
通常,應(yīng)成組地重載運(yùn)算符。例如,如果重載了相等運(yùn)算符,也應(yīng)重載不等運(yùn)算符。對(duì)于這個(gè)指導(dǎo)原則,唯一的例外是求補(bǔ)運(yùn)算符(~)和邏輯非運(yùn)算符(!)。下表列出了應(yīng)同時(shí)重載的成組運(yùn)算符。

Paste_Image.png

轉(zhuǎn)換運(yùn)算符
在用戶定義的結(jié)構(gòu)中,可重載運(yùn)算符以便能夠?qū)Χx的數(shù)據(jù)執(zhí)行常見的運(yùn)算,同樣,也可創(chuàng)建重載的轉(zhuǎn)換運(yùn)算符,以影響強(qiáng)制轉(zhuǎn)換和轉(zhuǎn)換過程。同樣,如果將轉(zhuǎn)換和強(qiáng)制轉(zhuǎn)換視為名稱特殊的函數(shù),則轉(zhuǎn)換重載也是一種特殊的方法重載。

ps:顯示轉(zhuǎn)換和隱式轉(zhuǎn)換
隱式轉(zhuǎn)換是屬于擴(kuò)大(widening)轉(zhuǎn)換,因?yàn)樵贾挡粫?huì)因轉(zhuǎn)換而丟失數(shù)據(jù)。顯式轉(zhuǎn)換屬于縮?。∟arrowing)轉(zhuǎn)換,因?yàn)樵贾悼赡芤蜣D(zhuǎn)換而丟失數(shù)據(jù)。
定義自己的轉(zhuǎn)換運(yùn)算符時(shí),應(yīng)牢記這些行為。如果定義的轉(zhuǎn)換可能丟失數(shù)據(jù),應(yīng)將其定義為顯式轉(zhuǎn)換;如果定義的轉(zhuǎn)換是安全的,即不會(huì)丟失數(shù)據(jù),就應(yīng)將其定義為隱式轉(zhuǎn)換。
內(nèi)置數(shù)據(jù)類型支持隱式轉(zhuǎn)換和顯式轉(zhuǎn)換,其中隱式轉(zhuǎn)換不需要特殊語(yǔ)法,但顯式轉(zhuǎn)換需要。對(duì)于自己定義的類型,可重載這些顯式轉(zhuǎn)換和隱式轉(zhuǎn)換,方法是聲明自己的轉(zhuǎn)換運(yùn)算符,其規(guī)則與聲明運(yùn)算符重載類似。
要聲明轉(zhuǎn)換運(yùn)算符,可定義一個(gè) public static方法,其名稱為關(guān)鍵字 operator,返回類型為要轉(zhuǎn)換到的類型。轉(zhuǎn)換運(yùn)算符只接受一個(gè)參數(shù),那就是要轉(zhuǎn)換的類型。
如果要聲明隱式轉(zhuǎn)換,就可在關(guān)鍵字operator前面加上implicit;否則,加上關(guān)鍵字explicit。有時(shí)結(jié)合使用轉(zhuǎn)換運(yùn)算符和運(yùn)算符重載,以減少要定義的運(yùn)算符重載。

2.2 構(gòu)造和初始化
就像必須給對(duì)象指定初始狀態(tài)一樣,結(jié)構(gòu)也如此。對(duì)于對(duì)象,這是通過構(gòu)造函數(shù)完成的,但結(jié)構(gòu)是值類型,無(wú)需調(diào)用構(gòu)造函數(shù)就可以創(chuàng)建結(jié)構(gòu)變量。例如,可像下面這樣創(chuàng)建一個(gè)NumberStruct變量:
NumberStruct ns1;
上述代碼創(chuàng)建了一個(gè)新變量,但是字段處于未初始化狀態(tài);如果此時(shí)試圖訪問字段,將發(fā)生編譯錯(cuò)誤。通過調(diào)用構(gòu)造函數(shù),可確保字段被初始化了。
結(jié)構(gòu)初始化的另一個(gè)方面是,不能將未完全初始化的結(jié)構(gòu)變量賦給另一個(gè)結(jié)構(gòu)變量,即不能將這樣的變量放在賦值運(yùn)算符右邊。這意味著下面的代碼合法:
NumberStruct ns1 = new NumberStruct();
NumberStruct ns2 = ns1;
但下面的代碼非法:
NumberStruct ns1;
NumberStruct ns2 = ns1;

ps:自定義默認(rèn)構(gòu)造函數(shù)
不同于類,結(jié)構(gòu)不能有自定義的默認(rèn)構(gòu)造函數(shù),也不能在構(gòu)造函數(shù)外面初始化結(jié)構(gòu)。因此,創(chuàng)建結(jié)構(gòu)時(shí),所有字段都被初始化為零值。
可以提供重載的構(gòu)造函數(shù),并利用構(gòu)造函數(shù)串接。然而,當(dāng)提供重載的構(gòu)造函數(shù)時(shí),必須初始化所有字段,這可在該構(gòu)造函數(shù)中顯式地進(jìn)行,也可通過串接構(gòu)造函數(shù)隱式地完成。
有趣的是,如果未顯式初始化的字段都可接受零值,就可串接默認(rèn)構(gòu)造函數(shù)。

struct NumberStruct
{
    public int Value;
}

class NumberClass
{
    public int value = 0;
}

class Test
{
    static void Main()
    {
        NumberStruct ns1 = new NumberStruct ();
        NumberStruct ns2 = ns1;
        ns2.Value = 42;

        NumberClass nc1 = new NumberClass ();
        NumberClass nc2 = nc1;
        nc2.value = 42;
        Console.WriteLine ("Struct:{0),{1}", ns1.Value, ns2.Value);
        Console.WriteLine ("Class:{0),{1}", nc1.Value, nc2.Value);
    }
}

由于ns1和ns2都是值類型NumberStruct,它們有各自的存儲(chǔ)空間,因此給ns2.Number賦值不會(huì)影響ns1.Number的值。然而,由于nc1和nc2都是引用類型,并且指向同一個(gè)存儲(chǔ)位置,因此給nc2.Number賦值將影響nc1.Number的值。
ps:使用屬性還是公有字段
對(duì)于結(jié)構(gòu)應(yīng)使用屬性還是公有字段存在一些爭(zhēng)議。有些人認(rèn)為總是應(yīng)該使用屬性,即使是在結(jié)構(gòu)這樣的簡(jiǎn)單類型中;而有些人認(rèn)為,在結(jié)構(gòu)中使用公有字段是能夠接受的。
雖然使用公有字段更容易,但是這導(dǎo)致值類型是可以修改的,而通常不希望這樣。定義自己的結(jié)構(gòu)時(shí),別忘了它們是值類型,應(yīng)像字符串一樣是不可修改的。為此,應(yīng)提供可用于設(shè)置私有字段的構(gòu)造函數(shù),并提供只讀屬性用于獲取私有字段的值。

附:C#中一些易混淆概念——構(gòu)造函數(shù)、this關(guān)鍵字、部分類、枚舉

1.構(gòu)造函數(shù)

我們先創(chuàng)建一個(gè)類,如下面的代碼:

class Program
    {
        static void Main(string[] args)
        {
     
        }
    }
  //創(chuàng)建一個(gè)Person類
    class Person
    {

    }

然后生成代碼。

我們使用.NET Reflector反編譯該程序集。會(huì)發(fā)現(xiàn)該類一被編譯,CLR會(huì)自動(dòng)的為該類創(chuàng)建一個(gè)默認(rèn)的構(gòu)造函數(shù)。如下圖:

Paste_Image.png

所以在創(chuàng)建該對(duì)象的時(shí)候,會(huì)默認(rèn)的為該類生成一個(gè)無(wú)參數(shù)的空方法體的構(gòu)造函數(shù)。如果我們不顯式的寫明構(gòu)造函數(shù),CLR會(huì)為我們調(diào)用默認(rèn)的構(gòu)造函數(shù)。

class Person
    {
        //聲明有實(shí)現(xiàn)的構(gòu)造函數(shù)
        public Person()
        {
            Console.WriteLine("我是超人!");
        }
    }

再次反編譯該程序集,會(huì)發(fā)現(xiàn)添加的構(gòu)造函數(shù)覆蓋了C#編譯器默認(rèn)為該類生成的構(gòu)造函數(shù),如下圖:

Paste_Image.png

所以,當(dāng)程序員手動(dòng)添加了任意類型的構(gòu)造函數(shù),C#編譯器就不會(huì)為該類添加默認(rèn)的構(gòu)造函數(shù)。

構(gòu)造函數(shù)的特點(diǎn):

①訪問修飾符一般是Public②沒有返回值,方法名與類名稱一致;

2.This關(guān)鍵字的作用

①this關(guān)鍵字代表當(dāng)前對(duì)象,當(dāng)前運(yùn)行在內(nèi)存中的那一個(gè)對(duì)象。我們添加如下的代碼:

private int nAge;

        public int NAge
        {
            get { return nAge; }
            set { nAge = value; }
        }

        //聲明有實(shí)現(xiàn)的構(gòu)造函數(shù)
        public Person()
        {
            this.NAge = 100;
            Console.WriteLine("我是超人!");
        }

這時(shí)候我們反編譯該程序集,會(huì)看到如下結(jié)果:

Paste_Image.png

可以看到this關(guān)鍵字代替的就是當(dāng)前的Person對(duì)象。

②this關(guān)鍵字后面跟“:”符號(hào),可以調(diào)用其它的構(gòu)造函數(shù)

我們?cè)偬砑尤缦碌拇a:

        #region 對(duì)象的構(gòu)造函數(shù)
        //聲明有實(shí)現(xiàn)的構(gòu)造函數(shù)
        public Person()
        {
            this.NAge = 100;
            Console.WriteLine("我是超人!");
        }

        public Person(int nAge)
        {
            Console.WriteLine("超人的年齡{0}", nAge);
        }
    //使用this關(guān)鍵字調(diào)用了第二個(gè)一個(gè)參數(shù)的構(gòu)造函數(shù)
        public Person(int nAge, string strName)
            : this(1)
        {
            Console.WriteLine("我是叫{0}的超人,年齡{1}", strName, nAge);
        }
        #endregion

我們創(chuàng)建該對(duì)象看看是否調(diào)用成功。在Main函數(shù)中添加如下代碼:

Person p = new Person(10,"強(qiáng)子");

我們運(yùn)行代碼,看到的打印結(jié)果如下:

Paste_Image.png

由結(jié)果我們可以分析出,當(dāng)含有兩個(gè)默認(rèn)參數(shù)的對(duì)象創(chuàng)建的時(shí)候應(yīng)該先調(diào)用了一個(gè)參數(shù)的構(gòu)造函數(shù)對(duì)對(duì)象進(jìn)行初始化,然后有調(diào)用了含有兩個(gè)參數(shù)的構(gòu)造函數(shù)對(duì)對(duì)象進(jìn)行初始化。

那么到底是不是這個(gè)樣子呢?看下邊的調(diào)試過程:

Paste_Image.png

通過上面的調(diào)試過程我們會(huì)發(fā)現(xiàn),當(dāng)構(gòu)造函數(shù)使用this關(guān)鍵字調(diào)用其它的構(gòu)造函數(shù)時(shí),首先調(diào)用的是該調(diào)用的構(gòu)造函數(shù),在調(diào)用被調(diào)用的構(gòu)造函數(shù),先執(zhí)行被調(diào)用的構(gòu)造函數(shù),在執(zhí)行直接調(diào)用的構(gòu)造函數(shù)。

為什么要這個(gè)順序執(zhí)行?因?yàn)槲覀兡J(rèn)的傳值是10,我們需要打印的超人的年齡是“10”,如果先執(zhí)行直接調(diào)用的構(gòu)造函數(shù),就會(huì)被被調(diào)用構(gòu)造函數(shù)覆蓋。

3.部分類

在同一命名空間下可以使用partial關(guān)鍵字聲明相同名稱的類(同一命名空間下默認(rèn)不允許出現(xiàn)相同的類名稱),叫做部分類或者伙伴類。

如下圖,當(dāng)在同一命名空間下聲明相同名稱的類,編譯器報(bào)錯(cuò):

Paste_Image.png

當(dāng)我們使用Partial關(guān)鍵字時(shí),可以順利編譯通過,如下圖:

Paste_Image.png

分別添加如下的代碼:

partial class  Person
    {
        private string strAddress;

        public string StrAddress
        {
            get { return strAddress; }
            set { strAddress = value; }
        }
        private string strNumber;

        public string StrNumber
        {
            get { return strNumber; }
            set { strNumber = value; }
        }

        public void Run()
        {

        }
    }

   
    partial class  Person
    {

        #region 對(duì)象屬性
        private int nAge;

        public int NAge
        {
            get { return nAge; }
            set { nAge = value; }
        }

        private string strName;

        public string StrName
        {
            get { return strName; }
            set { strName = value; }
        }
       
        #endregion

        #region 對(duì)象的構(gòu)造函數(shù)
        //聲明有實(shí)現(xiàn)的構(gòu)造函數(shù)
        public Person()
        {
            this.NAge = 100;
            Console.WriteLine("我是超人!");
        }

        public Person(int nAge)
        {
            Console.WriteLine("超人的年齡{0}", nAge);
        }

        public Person(int nAge, string strName)
            : this(1)
        {
            Console.WriteLine("我是叫{0}的超人,年齡{1}", strName, nAge);
        }
        #endregion

        public void Sing()
        {

        }
    }

我們?cè)俅畏淳幾g該程序集,會(huì)發(fā)現(xiàn)如下的結(jié)果:

Paste_Image.png

我們會(huì)發(fā)現(xiàn)使用Partial關(guān)鍵字的兩個(gè)同名類,被編譯成了同一個(gè)類。

所以部分類的特點(diǎn):

①必須在同一個(gè)命名空間下的使用Partial關(guān)鍵字的同名類

②部分類其實(shí)就是一個(gè)類,C#編譯器會(huì)把它們編譯成一個(gè)類

③在一個(gè)伙伴類中定義的變量可以在另一個(gè)伙伴類中訪問(因?yàn)樗麄兙褪且粋€(gè)類)。

4.Const關(guān)鍵字和Readonly關(guān)鍵字的區(qū)別

1)const關(guān)鍵字

在Main函數(shù)中添加如下的代碼:

        const string strName = "強(qiáng)子";
            Console.WriteLine("我的名字叫{0}",strName);

編譯過后,我反編譯該程序集發(fā)現(xiàn)如下結(jié)果:

Paste_Image.png

發(fā)現(xiàn)定義的常量并沒有出現(xiàn)在反編譯的代碼中,而且使用Const常量的地方被常量代替了。

2)readonly關(guān)鍵字

添加如下代碼:

class cat
    {
        readonly string reOnlyName = "強(qiáng)子";
        public cat()
        {
            Console.WriteLine(reOnlyName);
        }
    }

生成后反編譯該程序集發(fā)現(xiàn),如下結(jié)果:

Paste_Image.png

我們發(fā)現(xiàn)被readonly修飾的變量并沒有被賦值,這是什么回事呢?我們點(diǎn)擊cat類的構(gòu)造函數(shù)時(shí),看到如下結(jié)果:

Paste_Image.png

我們發(fā)現(xiàn)被readonly修飾的變量是在被調(diào)用的時(shí)候賦值的。

那么被readonly修飾的變量的是就是不可變的么?當(dāng)然不是,由反編譯的結(jié)果我們知道,readonly修飾的變量是在被調(diào)用的時(shí)候在構(gòu)造函數(shù)中被賦值的,那么我們可以在構(gòu)造函數(shù)中修改readonly的默認(rèn)值

添加如下代碼:

class cat
    {
        readonly string reOnlyName = "強(qiáng)子";
        public cat()
        {
            this.reOnlyName = "子強(qiáng)";
            Console.WriteLine(reOnlyName);
        }
    }

在Main()函數(shù)中添加如下的代碼:

  cat ct = new cat();

運(yùn)行結(jié)果如下:

Paste_Image.png

說(shuō)明我們成功在構(gòu)造函數(shù)中修改了readonly變量的值。

readonly和const的區(qū)別:

const常量在聲明的時(shí)候就必須賦初始值,這樣聲明變量可以提高程序的運(yùn)行效率。而readonly變量聲明時(shí)可以不賦初始值,但一定要早構(gòu)造函數(shù)中賦初始值。

也就是說(shuō),const變量在編譯的時(shí)候就要確定常量的值,而readonly是在運(yùn)行的時(shí)候確定該變量的值的。

5.解析枚舉

枚舉的級(jí)別和類的級(jí)別一樣,可以自定義數(shù)據(jù)類型,可以在枚舉名稱后使用“:”來(lái)指明枚舉類型??慈缦麓a:

//定義一個(gè)方向的枚舉類型,枚舉成員使用","分割
    enum Direction:string
    {
        east,
        west,
        south,
        north
    }

編譯會(huì)報(bào)錯(cuò),錯(cuò)誤信息如下:

Paste_Image.png

由此我們可以知道枚舉的數(shù)據(jù)類型是值類型。

因?yàn)槊杜e是數(shù)據(jù)類型,所以可以直接聲明訪問,如下代碼:

class Program
    {
        static void Main(string[] args)
        {
            //枚舉是數(shù)據(jù)類型可以直接聲明
            Direction dr = Direction.east;

            Console.WriteLine(dr);

            Console.ReadKey();
        }
    }

    //定義一個(gè)方向的枚舉類型,枚舉成員使用","分割
    enum Direction
    {
        east,
        west,
        south,
        north
    }

也可以這樣訪問枚舉類型

class Program
    {
        static void Main(string[] args)
        {
            //枚舉是數(shù)據(jù)類型可以直接聲明
          // Direction dr = Direction.east;

            Person p=new Person();
            //直接調(diào)用枚舉變量
            p.dir = Direction.east;
            Console.WriteLine(p.dir);

            Console.ReadKey();
        }
    }

    class Person
    {
        private string strName;
        //直接聲明枚舉變量
        public Direction dir;
    }

每一個(gè)枚舉成員都對(duì)應(yīng)了一個(gè)整型的數(shù)值,這個(gè)數(shù)值默認(rèn)從0開始遞增,可以通過強(qiáng)制轉(zhuǎn)換獲取該枚舉所代表的值。可以通過如下的代碼訪問:

        Direction dr = Direction.east;
            int i = (int)dr;

我們還可以手動(dòng)為每一個(gè)枚舉成員賦值,代表的是整型數(shù)值,賦值后該枚舉成員所代表的值就是所賦的值。如下代碼:

enum Direction
    {
        east=1,
        west=0,
        south=2,
        north=3
    }

將字符串轉(zhuǎn)換成枚舉

      string strDir = "east";
            //將字符串轉(zhuǎn)換成枚舉類型
            Direction d1=(Direction)Enum.Parse(typeof(Direction),strDir);
            //轉(zhuǎn)換的時(shí)候忽略大小寫
            Direction d2 = (Direction)Enum.Parse(typeof(Direction), strDir,true);

最后我們?cè)賮?lái)探究一個(gè)空指針異常的問題

首先我們先聲明一個(gè)Dog類:

class Dog
    {
        private int nAge;

        public int NAge
        {
            get { return nAge; }
            set { nAge = value; }
        }
        private string strName;

        public string StrName
        {
            get { return strName; }
            set { strName = value; }
        }
    }

在Main()函數(shù)中我們這樣調(diào)用


      Dog d = null;
            d.StrName = "旺旺";

結(jié)果會(huì)報(bào)錯(cuò),如下圖

Paste_Image.png

我們已經(jīng)為屬性,封裝字段了,但是為什么沒有辦法給字段賦值呢?我們就來(lái)探究一下這個(gè)問題。

當(dāng)我們實(shí)例化Dog對(duì)象,即

Dog d = new Dog();

.NET Framwork做了什么工作呢?如下圖:

Paste_Image.png

那為什么會(huì)報(bào)錯(cuò)呢,原因如下圖:

Paste_Image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 4,200評(píng)論 1 10
  • 前言 人生苦多,快來(lái) Kotlin ,快速學(xué)習(xí)Kotlin! 什么是Kotlin? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,703評(píng)論 9 118
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,686評(píng)論 1 51
  • Hello Word 在屏幕上打印“Hello, world”,可以用一行代碼實(shí)現(xiàn): 你不需要為了輸入輸出或者字符...
    restkuan閱讀 3,366評(píng)論 0 6
  • 人們都說(shuō),高中生活好比地獄,而大學(xué)是天堂,是象牙塔。對(duì)于沒有考進(jìn)理想大學(xué)的我來(lái)說(shuō),這種說(shuō)法實(shí)在荒謬。大學(xué)更...
    鑲鉆白骨精閱讀 299評(píng)論 0 0

友情鏈接更多精彩內(nèi)容