對象初始化之外的構造函數break封裝嗎?C#對象初始化選項
鑑於:
class MyClass
{
public string _aString;
}
不應該_aString構件是專用的和經由到構造函數的調用(構造這裏省略)實例:
MyClass test = new MyClass("test");
代替對象初始化的替代方法:
MyClass test = new MyClass { _aString = "Test" };
對象初始化之外的構造函數break封裝嗎?C#對象初始化選項
鑑於:
class MyClass
{
public string _aString;
}
不應該_aString構件是專用的和經由到構造函數的調用(構造這裏省略)實例:
MyClass test = new MyClass("test");
代替對象初始化的替代方法:
MyClass test = new MyClass { _aString = "Test" };
「不對對象初始化構造函數中斷外封裝?」
那麼,沒有。正如您正確指出的那樣,您只能初始化當前範圍內已可訪問的屬性。 (公共,內部等)
這種Intialization實際上只是構造一個類和爲屬性賦值的一些語法糖,對於匿名類和Linq select子句非常有用。
通常認爲暴露公共fi字段......在某些情況下它可能是可接受的,例如,如果該字段被標記爲readonly
(這意味着它必須在構造函數中設置)。相反,你應該讓這個私人領域,並通過一個屬性,它可能會或可能不會是隻讀的,這取決於其目的暴露它:
class MyClass
{
private string _aString;
public string AString
{
get { return _aString; }
// uncomment to make the property writable
//set { _aString = value; }
}
}
這取決於該變量的目的。如果程序員只能在初始化時設置變量,但之後無法訪問變量,那麼我將使用私有變量。如果您希望班級用戶隨時可以設置/讀取變量,請將其公開。
當你有
public string _aString;
真的,當你因爲這是已經曝光的初始化這個值無關緊要。所以,當我們想談論初始化時,我們應該將這個字符串移入屬性。比談論封裝是有道理的。
所以,想象我們有一些字符串。最初有兩種初始化方法。一個是在構造函數內部執行,第二個是惰性初始化(當請求這些數據時初始化)。
是的,通過構造函數初始化,並添加屬性以允許(或不)訪問數據。
class MyClass {
private string _aString;
string MyProperty {
get { return this._aString; }
// you can make this private or protected
set { this._aString = value; }
}
}
如果你認爲屬性作爲getter和setters,我不相信它會打破封裝。但是你應該注意到你沒有使用一個Property,你已經使用了一個實例變量。事實上,我不相信它會像你的榜樣那樣工作。檢查這一個:
class MyClass {
private string aString;
public string AString {
get { return aString; }
set {aString = value; }
}
}
MyClass test = new MyClass {
AString = "test"
};
在這種情況下,您通過它的存取訪問私人領域。這就像使用無參數構造函數並稍後設置值。
直接設置公共字段在對象初始化器中是一個好的方法(從語言語義角度來看,不是正確的設計)。 – 2009-07-08 23:17:21
如果你問新對象初始化速記是否打破封裝,那麼答案是否定的。您只能使用新方法設置公開作用域的成員。
MyClass test = new MyClass { _aString = "Test" };
相同
MyClass test = new MyClass();
test._aString = "Test";
要顯示在C#類的對象公衆不但從「面向對象編程中的」點打破「封裝」。
從「良好實踐」的角度來看,這不是一件好事,因爲如果您更改更新此值(檢查,...)的行爲,它允許外部代碼使用此類。
哇! 5個答案在任何時間!感謝大家。 此代碼來自一本關於C#的書。我很好奇這是否是最佳做法。 – 2009-07-08 23:26:58