C#的“屬性”封裝
C#和delphi一樣,擁有“屬性”這一個概念。使用慣了c/c++,剛開始接觸類型屬性還真有點不是很適應。C#中“屬性”具體的用法如下:
class Employee
{
private int empID;
private float currPay;
private string empName;
private int empAge;
public int Age
{
get { return empAge;}
set { empAge = value; }
}
public Employee() { }
public Employee(string name, int age, int id, float pay)
{
empName = name;
empID = id;
empAge = age;
currPay = pay;
}
}
這裏,Age相當於Employee中的一個的“屬性”,我們可以認爲它是內部私有成員empAge的一個“別名”,它起到了兩個作用:1.隱藏了內部的私有成員變量 2.簡練的完成了設置set和獲得get私有變量的功能。以前在c++中實現上面獲取/修改成員變量的功能的時候,我們可能會更多的使用set***() 和get***()的方法。但是在c#裏面,還是強烈推薦使用屬性來完成對用的成員變量的操作。
當我們使用上面的類型屬性機制,要修改私有成員變量empAge,那麼可以寫爲:
Employee joe = new Employee();
Joe.Age = 50; // 老員工
注意點:
運行vs的附加工具ildasm,載入剛纔編譯好的代碼employeev.exe,我們可以非常清楚的看到employee類裏面的age屬性實際上是被映射到CLR內部調用的get_Age()以及set_Age(int32 )的方法,CLR再一次爲我們程序員解放勞動生產力做出了傑出的貢獻。(感謝大神Anders Hejlsberg )
所以,當我們編寫好了age屬性,試圖再編寫set,get方法的時候:
public int get_Age()
{
return empAge;
}
public void set_Age(int age)
{
empAge = age;
}
Csc編譯器是不會放過你的:
當然了,你寫成
public int get_age()
{
return empAge;
}
public void set_age(int age)
{
empAge = age;
}
編譯器還是會允許你冗餘的製造代碼的。
所以,我們可以得出結論:
當我們只是編制了類似Age之類的 類型屬性之後,clr會自動的映射到它生成的set_屬性名、get_屬性名方法 ,所以當你自以爲是的顯示編制了同名的 set_屬性名()、get_屬性名()之後,編譯器會提示錯誤。畫蛇添足的事情還是少幹爲好,畢竟c#在背後已經爲我們默默完成了很多實用的功能。
在這裏,不禁又生出一個疑問:在c#裏,對象中“屬性”的內存佈局又是怎麼樣的呢?它的實際開銷又有多大呢?值得繼續研究…..