程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#3.0中自動屬性和對象初始化器

C#3.0中自動屬性和對象初始化器

編輯:關於C#

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代碼中我們看到了 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

3總結:

自動屬性和對象初始化器都是 C#3.0提供的語法級別的功能改進,是一種語法糖,是編寫代碼的效率更高,將 一些重復性的工作交給編譯器來做,但是這種改變,也增加了代碼的不透明性, 這點在隱式類型中體現的更為突出,增加了代碼理解的難度,這些僅僅是提供給 代碼編寫人員的一種選擇,如果不喜歡也可以按照原來的方式來書寫自己的代碼 也未嘗不可。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved