2009-07-08 52 views
5

對象初始化之外的構造函數break封裝嗎?C#對象初始化選項

鑑於:

class MyClass 
{ 
    public string _aString; 
} 

不應該_aString構件是專用的和經由到構造函數的調用(構造這裏省略)實例:

MyClass test = new MyClass("test"); 

代替對象初始化的替代方法:

MyClass test = new MyClass { _aString = "Test" }; 
+0

哇! 5個答案在任何時間!感謝大家。 此代碼來自一本關於C#的書。我很好奇這是否是最佳做法。 – 2009-07-08 23:26:58

回答

6

「不對對象初始化構造函數中斷外封裝?」

那麼,沒有。正如您正確指出的那樣,您只能初始化當前範圍內已可訪問的屬性。 (公共,內部等)

這種Intialization實際上只是構造一個類和爲屬性賦值的一些語法糖,對於匿名類和Linq select子句非常有用。

5

通常認爲暴露公共fi字段......在某些情況下它可能是可接受的,例如,如果該字段被標記爲readonly(這意味着它必須在構造函數中設置)。相反,你應該讓這個私人領域,並通過一個屬性,它可能會或可能不會是隻讀的,這取決於其目的暴露它:

class MyClass 
{ 
    private string _aString; 
    public string AString 
    { 
     get { return _aString; } 
     // uncomment to make the property writable 
     //set { _aString = value; } 
    } 
} 
0

這取決於該變量的目的。如果程序員只能在初始化時設置變量,但之後無法訪問變量,那麼我將使用私有變量。如果您希望班級用戶隨時可以設置/讀取變量,請將其公開。

0

當你有
public string _aString;
真的,當你因爲這是已經曝光的初始化這個值無關緊要。所以,當我們想談論初始化時,我們應該將這個字符串移入屬性。比談論封裝是有道理的。
所以,想象我們有一些字符串。最初有兩種初始化方法。一個是在構造函數內部執行,第二個是惰性初始化(當請求這些數據時初始化)。

0

是的,通過構造函數初始化,並添加屬性以允許(或不)訪問數據。

class MyClass { 
private string _aString; 
string MyProperty { 
        get { return this._aString; } 
        // you can make this private or protected 
        set { this._aString = value; } 

        } 
} 
1

如果你認爲屬性作爲getter和setters,我不相信它會打破封裝。但是你應該注意到你沒有使用一個Property,你已經使用了一個實例變量。事實上,我不相信它會像你的榜樣那樣工作。檢查這一個:

class MyClass { 
    private string aString; 

    public string AString { 
     get { return aString; } 
     set {aString = value; } 
    } 
} 
MyClass test = new MyClass { 
    AString = "test" 
}; 

在這種情況下,您通過它的存取訪問私人領域。這就像使用無參數構造函數並稍後設置值。

+1

直接設置公共字段在對象初始化器中是一個好的方法(從語言語義角度來看,不是正確的設計)。 – 2009-07-08 23:17:21

0

如果你問新對象初始化速記是否打破封裝,那麼答案是否定的。您只能使用新方法設置公開作用域的成員。

MyClass test = new MyClass { _aString = "Test" }; 

相同

MyClass test = new MyClass(); 
test._aString = "Test"; 
0

要顯示在C#類的對象公衆不但從「面向對象編程中的」點打破「封裝」。

從「良好實踐」的角度來看,這不是一件好事,因爲如果您更改更新此值(檢查,...)的行爲,它允許外部代碼使用此類。