C#
中定義屬性更加方便
不用再在像之前的版本那樣的繁瑣
需要先定義存儲數據的字段
然後再定義屬性器
現在只需要定義屬性器就可以了
其它的有編譯器自動為我們完成
就可以省去定義字段時需要的那些時間
在對象初始化的時候我們可在對象構造的時候實現對象屬性的初始化工作
和集合初始化類似
匿名屬性
定義屬性如下
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# 之前的寫法如下
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; }
}
}
僅從代碼量上就前者比後者減少了/的代碼這對提高效率是顯而易見的那麼這些代碼都到哪裡去了呢?其實那些額外的代碼都是由編譯器為我們完成的編譯器會將那些我們省去的代碼編譯成托管IL代碼的時候補進去兩者中代碼在最終生成的IL代碼的體積是差不多的
上圖中的IL代碼中我們看到了 k_BackingField之類的字段就是編譯器自動產生的字段代碼
對象初始化器
原來的對象初始化都要進行先創建構造方法然後才能進行成員的相關操作C# 提供了對象成員的直接初始化的能力和初始化一個集合或者是數組一樣來初始化對象
相對來看通過對象初始化器對上面的的Employee類進行進行調用
Employee employee = new Employee { Id = Name = 藍之風 Age = BirthDate =
Sex = 男 };
ConsoleWriteLine(編號;{} employeeId);
ConsoleWriteLine(姓名:{} employeeName);
ConsoleWriteLine(年齡:{} employeeAge);
ConsoleWriteLine(生日:{} employeeBirthDate);
ConsoleWriteLine(性別:{} employeeSex);
ConsoleWriteLine(請按任意鍵繼續);
ConsoleReadLine();
這句
Employee employee = new Employee { Id = Name = 藍之風 Age = BirthDate =
Sex = 男 };
就是對象的初始化看到代碼很簡潔輸出的結果如下
在C#之前的做法是
Employee employee = new Employee();
employeeId = ;
employeeName = 藍之風;
employeeAge = ;
employeeBirthDate = ;
employeeSex = 男;
ConsoleWriteLine(編號;{} employeeId);
ConsoleWriteLine(姓名:{} employeeName);
ConsoleWriteLine(年齡:{} employeeAge);
ConsoleWriteLine(生日:{} employeeBirthDate);
ConsoleWriteLine(性別:{} employeeSex);
ConsoleWriteLine(請按任意鍵繼續);
ConsoleReadLine();
或者通過重載構造方法的方式來初始化這些屬性二者的達到的效果是相同的但是前者使用起來方便了些代碼量減少了許多這個過程是怎麼完成的呢?其實C#本身並沒有太大的變化這些都是在語法上的一些改變使得編寫代碼的時候更方便效率更高把一些編譯器可以推斷出來完成的工作讓編譯器來做了編譯器在編譯程序的時候將我們沒有實現的代碼替我們實現來生成IL代碼的
method private hidebysig static void Main(string[] args) cil managed
{
entrypoint
// 代碼大小 (xaf)
maxstack
locals init ([] class CSEmployee employee
[] class CSEmployee <>g__initLocal)
IL_: nop
IL_: newobj instance void CSEmployee::ctor()
IL_: stloc
IL_: ldloc
IL_: ldci
IL_: callvirt instance void CSEmployee::set_Id(int)
IL_e: nop
IL_f: ldloc
IL_: ldstr bytearray (DD B E CE ) // KN
IL_: callvirt instance void CSEmployee::set_Name(string)
IL_a: nop
IL_b: ldloc
IL_c: ldcis
IL_e: callvirt instance void CSEmployee::set_Age(int)
IL_: nop
IL_: ldloc
IL_: ldstr
IL_a: callvirt instance void CSEmployee::set_BirthDate(string)
IL_f: nop
IL_: ldloc
IL_: ldstr bytearray ( ) // u
IL_: callvirt instance void CSEmployee::set_Sex(string)
IL_b: nop
IL_c: ldloc
IL_d: stloc
IL_e: ldstr bytearray ( F F B B D ) // S;{}
IL_: ldloc
IL_: callvirt instance int CSEmployee::get_Id()
IL_: box [mscorlib]SystemInt
IL_e: call void [mscorlib]SystemConsole::WriteLine(string
object)
IL_: nop
IL_: ldstr bytearray (D D A B D ) // YT:{}
IL_: ldloc
IL_a: callvirt instance string CSEmployee::get_Name()
IL_f: call void [mscorlib]SystemConsole::WriteLine(string
object)
IL_: nop
IL_: ldstr bytearray ( E F A B D ) // t^:{}
IL_a: ldloc
IL_b: callvirt instance int CSEmployee::get_Age()
IL_: box [mscorlib]SystemInt
IL_: call void [mscorlib]SystemConsole::WriteLine(string
object)
IL_a: nop
IL_b: ldstr bytearray (F E A B D ) // ue:{}
IL_: ldloc
IL_: callvirt instance string CSEmployee::get_BirthDate()
IL_: call void [mscorlib]SystemConsole::WriteLine(string
object)
IL_b: nop
IL_c: ldstr bytearray ( B A B D ) // `+R:{}
IL_: ldloc
IL_: callvirt instance string CSEmployee::get_Sex()
IL_: call void [mscorlib]SystemConsole::WriteLine(string
object)
IL_c: nop
IL_d: ldstr bytearray (F B FB E F E E E ED E E // cNa~~
E E ) //
IL_a: call void [mscorlib]SystemConsole::WriteLine(string)
IL_a: nop
IL_a: call string [mscorlib]SystemConsole::ReadLine()
IL_ad: pop
IL_ae: ret
} // end of method Program::Main
從上面的IL代碼中可以清晰的看到首先創建了Employee的實例然後才對相關的屬性進行賦值操作的
總結
自動屬性和對象初始化器都是C#提供的語法級別的功能改進是一種語法糖是編寫代碼的效率更高將一些重復性的工作交給編譯器來做但是這種改變也增加了代碼的不透明性這點在隱式類型中體現的更為突出增加了代碼理解的難度這些僅僅是提供給代碼編寫人員的一種選擇如果不喜歡也可以按照原來的方式來書寫自己的代碼也未嘗不可
From:http://tw.wingwit.com/Article/program/net/201311/13185.html