Effective C# 條款1
屬性的優點:
-
遵循面向對象的原則
-
具有彈性
1. 1 遵循面向對象的原則
屬性在使我們可以將數據成員暴露為公有接口的同時,還為我們提供了在面向對象環境中所期望的封裝。從表面看起來像是數據成員,但內部卻是以方法實現。
public class TestClass
{
//成員變量
public string Name;
}
public class TestClass
{
//屬性
public string Name { get; set; }
}
TestClass testClass = new TestClass();
testClass.Name = "TestClass";
這段代碼非常簡潔和直觀。有人據此就認為以后如果有需要,再將 TestClass 類的數據成員 Name 替換為屬性OK了,而使用TestClass類型的代碼無需做任何改變。這種說法從某種程度上來講是對的。
屬性在被訪問的時候和數據成員看起來沒有什么差別。這正是 C#引入新的屬性語法的一個目標。但屬性畢竟不是數據,訪問屬性和訪問數據產生的是不同的 MSIL。在程序編譯后,編譯器在把程序編譯成為MSIL時,會自動把屬性中的get/set編譯成為兩個方法,所以屬性能夠獲得函數的全部好處。但實際區別我們可以通過如下的MSIL分析可知成員變量和屬性是存在區別的。

圖1 TestClass類編譯后的MSIL
通過圖1我們沒有找到Name屬性,取而代之的是兩個get_Name / set_Name方法,充分說明了屬性是通過方法的方式調用。

圖2成員變量MSIL

圖3屬性MSIL
大家注意盡管訪問屬性和訪問數據成員使用的是同樣的 C#源代碼,但是 C#編譯器卻將它們轉換為不同的IL代碼。
換句話說,雖然屬性和數據成員在源代碼層次上是兼容的,但是在二進制層次上卻不兼容。這意味著如果將一個類型的公有數據成員改為公有屬性,那么我們必須重新編譯所有使用該公有數據成員的C#代碼。
1.2 具有彈性
使用屬性在修改上也比成員變量更具有彈性,例如程序要判斷成員變量是否為空時,我們就需在代碼某處加上判斷邏輯,而屬性我們只需在屬性上加上判斷邏輯,省去了煩心查找要加邏輯的地方。
private string _name;
public string Name
{
get
{
if (_name == null)
return string.Empty;
return _name;
}
set
{
_name = value;
}
}
由于屬性是采用方法來實現的,因此為它們添加多線程支持就更加容易——直接在get和 set方法中提供同步數據訪問控制即可:
public string Name
{
get
{
lock( this )
{
return _name;
}
}
set
{
lock( this )
{
_name = value;
}
}
}
經驗總結:
只要打算將數據暴露在類型的公有接口或者受保護接口中,我們都應該使用屬性來實現。對于具有序列或者字典特征的類型,則應該采用索引器。
|
|
關于作者:[作者]:
JK_Rush從事.NET開發和熱衷于開源高性能系統設計,通過博文交流和分享經驗,歡迎轉載,請保留原文地址,謝謝。 |

使用屬性代替可訪問的數據成員。
浙公網安備 33010602011771號