2016-11-18 24 views
1

在一個類中,我們聲明類成員是私有的,但我們將屬性定義爲public。爲什麼集體成員是私人的,屬性是公開的?

例如:

public class student 
{ 
    private int StudentId; 
    private string StudentName; 
    private string Address; 
} 

和我們分配使用方法在此之後。

但是,如果我們使用屬性來獲取設置定義類似。

public class student 
{ 
    public int StudentId {get;set;}; 
    public string StudentName{get;set;}; 
    public string Address{get;set;}; 
} 

這背後的原因是什麼?

+2

寫在mockable和可測試的方式你不這樣做,因爲* *他們「類成員」或「屬性」(順便說一下,屬性也是成員,將它們分組爲靜態成員和實例成員更爲典型)。你通常想封裝實際的實現,所以當你訪問它們時沒有綁定邏輯的字段通常是私有的,而你可以同時控制寫入訪問(誰寫入)和綁定邏輯的屬性(當你寫)更經常公開。你想控制你的類型的公共表面,並隱藏實際的實現。 –

+0

沒有什麼強制你使用一個字段作爲私有或者屬性作爲公共的,但是通常變量是私有的,因爲這些類是內部使用的,屬性用於外部使用,因爲它們可以在get/set時執行代碼。 – Gusman

+2

此解決方案可能會清除您的情況:http://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property-in-c http://softwareengineering.stackexchange .com/questions/133015/private-variable-vs-property –

回答

1

類需要控制其公共成員的行爲:即控制他們做什麼

試想一下,例如,如果private string StudentName;作出public等所使用的外部代碼(課外student)。然後你決定要添加一個驗證來限制StudentName的長度 - 你怎麼能這樣做?您必須在代碼中找到所有實例(以及可能使用此類的其他人的代碼),該實例將設置值StudentName並在其中添加驗證。

如果你不使用public string Student {get; set;} - 你可以很容易地改變它是一個明確的屬性與驗證:

private string _student; 
public string Student 
{ 
    get { return _student; } 
    set { if(value.Length <= 20) _student = value; 
} 

即使用屬性使得它更容易在類的內部控制類成員的行爲,保持封裝和抽象

0

你是對的 - 屬性通常用作公共的。 雖然:您可以定義一個屬性這樣藏漢:

public int StudentId {get; private set;} 

這將使其他類讓你的財產的價值,但他們將無法改變它。

想象一下,如果您要開發一個像其中有許多複雜控件的程序集一樣的項目。如果你希望用戶能夠閱讀,控制中有什麼價值,因爲它被計算出來,你給它一個公共getter,但是一個私人setter,因爲你不想讓別人操縱裏面發生的事情。

1

這並不完全。真正的規則是:

定義所有成員的限制,因爲他們可以是。

因此,如果它可以是private然後它是private。否則,如果它必須是internalprotected工作,那麼它分別是internalprotected。否則,如果它必須protected internal工作,那麼它是protected internal。否則,它是public,因爲它必須是public才能正常工作(程序集之外的東西不會從它繼承它將不得不訪問它)。

現在,所有這一切說,通常我們會主要有private字段和大多數public屬性。

讓我們來考慮一下我們是否有public字段。這是有效的,將工作,甚至在非常有限的情況下甚至是有用的。但它也更脆弱。擁有它public可以讓任何其他代碼將它設置爲任何值,不管多麼愚蠢。沒關係,因爲當我們創建一個字段public時,我們說「沒有愚蠢的值」。*

但是,如果我們突然意識到存在一些愚蠢的值,或者我們需要在每次字段更改時都要做某件事,或者我們需要使用一些僅限財產的數據綁定。在這裏我們將不得不把這個領域變成一個財產,這是一個突破性的變化;任何使用這個類的代碼都必須重新編譯,如果我們是唯一使用這個類的人,但是如果它在一個正在被其他人使用的庫中,這並不是什麼大事。

如果它一直然而屬性,那麼我們剛剛不得不把一個自動財產{ get; set; }與自定義實現{ get { /* do stuff and return value */ } set { /* do stuff */ } }的屬性。從課外,看起來沒有什麼變化,我們沒有破壞任何東西。

因此,99.99%的時間,如果你打算做一個字段public你最好在那裏使用一個屬性,以防萬一。另一方面,如果我們有一個private屬性沒有邏輯,那麼getter和setter方法不會給我們帶來任何好處。不會有任何費用,但它們毫無意義。所以我們只需要使用一個字段。如果我們最終不得不在未來使用私有財產,那將是無關緊要的,因爲唯一需要重新編譯的代碼就是所討論的類,而且我們正在重新編譯它。

因此,我們以幾乎所有字段爲private並且幾乎所有不具有任何定製邏輯的屬性爲protectedpublic的情況結束。

*或者它是一個privateinternal類,我們從外面不能將它設置爲一些愚蠢的承諾,但它是更好地執行承諾比,如果你可以讓他們。

0

不直接設置字段,但通過屬性遵循面向對象的封裝原則。這包括一個類是它的對象包含的數據的老闆。一個類應該始終保持對數據訪問的控制權(無論是讀取還是寫入)。有時這意味着他們需要執行額外的步驟來確保數據的一致性。但即使他們不這樣做,事實上不應該隱藏給來電者,因爲這不關他們的業務(關注點分離)。因此簡單的規則是:沒有對象數據的快捷方式。如果你想得到一些,你必須要求班級給你。在C#中,這就是屬性的用途。

0

後面有使用性質,使他們的公共

  1. 標識類領域的公衆&暴露多重原因是有風險的,因爲你將 沒有什麼被分配&返回控制。

  2. 想要在值更改時進入調試器?只需在setter中添加一個斷點即可。

  3. 想要記錄所有訪問?只需將記錄添加到getter即可。 屬性用於數據綁定;字段不是。

  4. 在私人成員上添加驗證(例如,值不能設置爲負值)。

  5. 如果爲空,空或零,則返回一些默認值。

  6. 屬性可以聲明爲讀/寫,只讀或只寫。

  7. 其他好處,反射和DataBinding。

0

在這個最簡單的情況下沒有特殊原因。但是,如果您進一步研究開發 - 將會變得非常明確:您需要從實現中抽象出來並分離出一個接口,例如只是爲了在單元測試中嘲笑學生。所以,長期來看,你會相當需要的接口和性能,它只是一個習慣,它從一開始

public interface IStudent 
{ 
    int StudentId { get; set; } 
    string StudentName { get; set; } 
    string Address { get; set; } 
} 

public class Student : IStudent 
{ 
    public int StudentId { get; set; } 
    public string StudentName { get; set; } 
    public string Address { get; set; } 
} 
相關問題