C#3.0之自動屬性&對象初始化器

來源:互聯網
上載者:User

C#3.0中定義屬性更加方便,不用再在像之前的版本那樣的繁瑣,需要先定義儲存資料的欄位,然後再定義屬性器,現在只需要定義屬性器就可以了,其它的有編譯器自動為我們完成,就可以省去定義欄位時需要的那些時間;在對象初始化的時候我們可在物件建構的時候實現對象屬性的初始化工作,和集合初始化類似。

1.匿名屬性

定義屬性如下:

    public class Employee    {        public int Id { get; set; }        public string Name { get; set; }        public string Sex { get; set; }        public int Age { get; set; }        public string BirthDate { get; set; }    }
在C#3.0 之前的寫法如下:
    public class Employee    {        private int _id;        private string _name;        private string _sex;        private int _age;        private string _birthDate;        public int Id        {            get { return _id; }            set { _id = value; }        }        public string Name        {            get { return _name; }            set { _name = value; }        }        public string Sex        {            get { return _sex; }            set { _sex = value; }        }        public int Age        {            get { return _age; }            set { _age = value; }        }        public string BirthDate        {            get { return _birthDate; }            set { _birthDate = value; }        }    }

僅從代碼量上就前者比後者減少了2/3的代碼,這對提高效率是顯而易見的,那麼這些代碼都到哪裡去了呢?其實那些額外的代碼都是由編譯器為我們完成的,編譯器會將那些我們“省去"的代碼編譯成託管IL代碼的時候補進去,兩者中代碼在最終產生的IL代碼的體積是差不多的。

中的IL代碼中我們看到了 <xxx>k_BackingField之類的欄位就是編譯器自動產生的欄位代碼。

2.對象初始化器,原來的對象初始化都要進行先建立構造方法,然後才能進行成員的相關操作,C#3.0 提供了對象成員的直接初始化的能力,和初始化一個集合或者是數組一樣來初始化對象。

相面來看,通過對象初始化器對上面的的Employee類進行進行調用:

            Employee employee = new Employee { Id = 1, Name = "藍之風", Age = 24, BirthDate = "1984-10-21", Sex = "男" };            Console.WriteLine("編號;{0}", employee.Id);            Console.WriteLine("姓名:{0}", employee.Name);            Console.WriteLine("年齡:{0}", employee.Age);            Console.WriteLine("生日:{0}", employee.BirthDate);            Console.WriteLine("性別:{0}", employee.Sex);            Console.WriteLine("請按任意鍵繼續...");              Console.ReadLine();

這句

       Employee employee = new Employee { Id = 1, Name = "藍之風", Age = 24, BirthDate = "1984-10-21", Sex = "男" };

就是對象的初始化,看到代碼很簡潔,輸出的結果如下:

在C#3.0之前的做法是:

            Employee employee = new Employee();            employee.Id = 1;            employee.Name = "藍之風";            employee.Age = 24;            employee.BirthDate = "1984-10-21";            employee.Sex = "男";                                        Console.WriteLine("編號;{0}", employee.Id);            Console.WriteLine("姓名:{0}", employee.Name);            Console.WriteLine("年齡:{0}", employee.Age);            Console.WriteLine("生日:{0}", employee.BirthDate);            Console.WriteLine("性別:{0}", employee.Sex);            Console.WriteLine("請按任意鍵繼續...");              Console.ReadLine();
或者通過重載構造方法的方式來初始化這些屬性,二者的達到的效果是相同的,但是前者使用起來方便了些,代碼量減少了許多,這個過程是怎麼完成的呢?其實C#本身並沒有太大的變化,這些都是在文法上的一些改變,使得編寫代碼的時候更方便效率更高,把一些編譯器可以推斷出來完成的工作讓編譯器來做了,編譯器在編譯器的時候將我們沒有實現的代碼替我們實現來產生IL代碼的:
method private hidebysig static void  Main(string[] args) cil managed{  .entrypoint  // 代碼大小       175 (0xaf)  .maxstack  2  .locals init ([0] class CS30.Employee employee,           [1] class CS30.Employee '<>g__initLocal0')  IL_0000:  nop  IL_0001:  newobj     instance void CS30.Employee::.ctor()  IL_0006:  stloc.1  IL_0007:  ldloc.1  IL_0008:  ldc.i4.1  IL_0009:  callvirt   instance void CS30.Employee::set_Id(int32)  IL_000e:  nop  IL_000f:  ldloc.1  IL_0010:  ldstr      bytearray (DD 84 4B 4E CE 98 )                               // ..KN..  IL_0015:  callvirt   instance void CS30.Employee::set_Name(string)  IL_001a:  nop  IL_001b:  ldloc.1  IL_001c:  ldc.i4.s   24  IL_001e:  callvirt   instance void CS30.Employee::set_Age(int32)  IL_0023:  nop  IL_0024:  ldloc.1  IL_0025:  ldstr      "1984-10-21"  IL_002a:  callvirt   instance void CS30.Employee::set_BirthDate(string)  IL_002f:  nop  IL_0030:  ldloc.1  IL_0031:  ldstr      bytearray (37 75 )                                           // 7u  IL_0036:  callvirt   instance void CS30.Employee::set_Sex(string)  IL_003b:  nop  IL_003c:  ldloc.1  IL_003d:  stloc.0  IL_003e:  ldstr      bytearray (16 7F F7 53 3B 00 7B 00 30 00 7D 00 )             // ...S;.{.0.}.  IL_0043:  ldloc.0  IL_0044:  callvirt   instance int32 CS30.Employee::get_Id()  IL_0049:  box        [mscorlib]System.Int32  IL_004e:  call       void [mscorlib]System.Console::WriteLine(string,                                                                object)  IL_0053:  nop  IL_0054:  ldstr      bytearray (D3 59 0D 54 3A 00 7B 00 30 00 7D 00 )             // .Y.T:.{.0.}.  IL_0059:  ldloc.0  IL_005a:  callvirt   instance string CS30.Employee::get_Name()  IL_005f:  call       void [mscorlib]System.Console::WriteLine(string,                                                                object)  IL_0064:  nop  IL_0065:  ldstr      bytearray (74 5E 84 9F 3A 00 7B 00 30 00 7D 00 )             // t^..:.{.0.}.  IL_006a:  ldloc.0  IL_006b:  callvirt   instance int32 CS30.Employee::get_Age()  IL_0070:  box        [mscorlib]System.Int32  IL_0075:  call       void [mscorlib]System.Console::WriteLine(string,                                                                object)  IL_007a:  nop  IL_007b:  ldstr      bytearray (1F 75 E5 65 3A 00 7B 00 30 00 7D 00 )             // .u.e:.{.0.}.  IL_0080:  ldloc.0  IL_0081:  callvirt   instance string CS30.Employee::get_BirthDate()  IL_0086:  call       void [mscorlib]System.Console::WriteLine(string,                                                                object)  IL_008b:  nop  IL_008c:  ldstr      bytearray (27 60 2B 52 3A 00 7B 00 30 00 7D 00 )             // '`+R:.{.0.}.  IL_0091:  ldloc.0  IL_0092:  callvirt   instance string CS30.Employee::get_Sex()  IL_0097:  call       void [mscorlib]System.Console::WriteLine(string,                                                                object)  IL_009c:  nop  IL_009d:  ldstr      bytearray (F7 8B 09 63 FB 4E 0F 61 2E 95 E7 7E ED 7E 2E 00   // ...c.N.a...~.~..                                  2E 00 2E 00 )                                     // ....  IL_00a2:  call       void [mscorlib]System.Console::WriteLine(string)  IL_00a7:  nop  IL_00a8:  call       string [mscorlib]System.Console::ReadLine()  IL_00ad:  pop  IL_00ae:  ret} // end of method Program::Main從上面的IL代碼中可以清晰的看到,首先建立了Employee的執行個體,然後才對相關的屬性進行賦值操作的。
3總結:
自動屬性和對象初始化器都是C#3.0提供的文法層級的功能改進,是一種文法糖,是編寫代碼的效率更高,將一些重複性的工作交給編譯器來做,但是這種改變,也增加了代碼的不透明性,這點在隱式類型中體現的更為突出,增加了代碼理解的難度,這些僅僅是提供給代碼編寫人員的一種選擇,如果不喜歡也可以按照原來的方式來書寫自己的代碼也未嘗不可。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.