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程式碼的體積是差不多的。
2.物件初始化器,原來的物件初始化都要進行先建立構造方法,然後才能進行成員的相關操作,C#3.0 提供了物件成員的直接初始化的能力,和初始化一個集合或者是陣列一樣來初始化物件。
相面來看,通過物件初始化器對上面的的Employee類進行進行呼叫:
Employee employee = new Employee { Id = 1, Name = "藍之風", Age = 24, BirthDate = "1984-10-21", Sex = "男" }; BirthDate = "1984-10-21", Sex = "男" }; |
在C#3.0之前的做法是:
Employee employee = new Employee(); |
或者通過過載構造方法的方式來初始化這些屬性,二者的達到的效果是相同的,但是前者使用起來方便了些,程式碼量減少了許多,這個過程是怎麼完成的呢? 其實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
3總結:自 動屬性和物件初始化器都是C#3.0提供的語法級別的功能改進,是一種語法糖,是編寫程式碼的效率更高,將一些重複性的工作交給編譯器來做,但是這種改變, 也增加了程式碼的不透明性,這點在隱式型別中體現的更為突出,增加了程式碼理解的難度,這些僅僅是提供給程式碼編寫人員的一種選擇,如果不喜歡也可以按照原來的 方式來書寫自己的程式碼也未嘗不可。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-600454/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- javascript獲取物件直接量中的屬性和屬性值JavaScript物件
- 自動生成屬性
- python實現在類中動態新增屬性和生成物件Python物件
- JavaScript物件的資料屬性與訪問器屬性JavaScript物件
- MVC5之表單集合資料自動繫結到物件屬性(集合)中MVC物件
- Vue中計算屬性和偵聽器Vue
- css屬性與js中style物件的屬性對應表CSSJS物件
- JavaScript刪除和清空物件屬性JavaScript物件
- Wordpress自動給圖片新增alt和title屬性
- 深入理解物件的資料屬性與訪問器屬性物件
- javascript基礎(物件,物件屬性,屬性基本和引用資料型別,字面量建立物件,垃圾回收,屬性的列舉)(十三)JavaScript物件資料型別
- CSS瀏覽器相容性的4個解決方案:瀏覽器CSS樣式初始化、瀏覽器私有屬性,CSS hack語法和自動化外掛CSS瀏覽器
- js物件屬性JS物件
- JavaScript訪問物件的屬性和方法JavaScript物件
- jQuery事件物件event的屬性和方法jQuery事件物件
- js為物件新增和刪除屬性JS物件
- Array String物件的方法和屬性物件
- 獲取物件屬性型別、屬性名稱、屬性值的研究:反射和JEXL解析引擎物件型別反射
- javascript原型物件的屬性不能夠覆蓋物件自有屬性JavaScript原型物件
- 【Vue】探索物件屬性變動在Vue中的具體表現Vue物件
- js自動新增的物件屬性並非完全按照新增的順序排列JS物件
- C#索引器和屬性C#索引
- GObject的物件屬性GoObject物件
- Object物件的屬性Object物件
- DataView物件buffer屬性View物件
- 修改物件私有屬性物件
- 理解Python中的類物件、例項物件、屬性、方法Python物件
- JavaScript 判斷物件中是否有某屬性JavaScript物件
- 物件導向中Object常用屬性總結物件Object
- PHP動態屬性和stdclassPHP
- 使用 tpl 標籤和 for 讀取物件屬性值中的陣列物件陣列
- HTML DOM之document物件的屬性和方法HTML物件
- 元物件、 屬性 和 反射程式設計物件反射程式設計
- 一、訪問物件屬性和方法的操作物件
- CAD屬性編輯操作——物件屬性教程物件
- python物件屬性管理(2):property管理屬性Python物件
- Python __dict__屬性:檢視物件內部所有屬性名和屬性值組成的字典Python物件
- javascript如何動態刪除或者新增物件屬性JavaScript物件