2009-08-14 59 views
50

在我看到的大部分代碼中(在SO上,codeproject.com和我傾向於在我自己的代碼中執行此操作),我已經看到爲類的每個單獨私有字段創建的公共屬性,即使它們是像最基本類型的get; set;我應該使用公共財產和私人領域或公共領域的數據?

private int myInt; 
public int MyInt 
{ 
    get { return myInt; } 
    set { myInt = value } 
} 

我的問題是:它如何從不同:

public int MyInt; 

,如果我們要使用屬性,而不是公共領域,爲什麼我們要在這個特定使用它們案件? (我不是在談論更復雜的例子,其中getter和setter實際上做了一些特殊的事情,或者只有一個get或set(只讀/寫)而不是返回/設置私有字段的值。它似乎沒有添加任何額外的封裝,只在IntelliSense中給出一個漂亮的圖標,並放置在類圖的特殊部分!

+0

這真的不是重複的嗎? – 2009-08-14 12:49:09

+0

很難相信這個問題在這裏沒有被問到,直到現在! – 2009-12-23 08:32:59

+0

這是,我認爲它。當我追捕它時,請繼續...... – RCIX 2010-02-03 09:05:37

回答

30

請參閱本文http://blog.codinghorror.com/properties-vs-public-variables/

具體

  • 思考的工作方式不同的變量與屬性,所以如果依靠反射,它更容易使用的所有屬性。
  • 您無法對變量進行數據綁定。
  • 將變量更改爲屬性是一項重大改變。
+1

使用屬性優於使用字段,因爲 您可以更改get和set塊中的語句,而無需更改依賴於屬性的類。 – user2211290 2016-08-23 10:46:51

0

原因有很多。

主要是:

  • 你可以做一些其他的功能,當變量被設置
  • 您可以防止設置,並提供了獲得
  • 的性能(數據綁定一些「東西」只工作,例如)
  • 您可以隱藏該屬性的實現[也許它是一個ViewState變量,在ASP.NET中)。
5

那麼它確實有所作爲。公共數據可以在對象實例不知道它的情況下進行更改。使用getter和setter對象總是會意識到已經做出更改。請記住,封裝數據只是實現更好結構化設計的第一步,它本身並不是最終目標。

0

問題是 - 如果你想要確保每次引用myInt時發生了特殊情況(寫入日誌文件,將其更改爲42等),該怎麼辦?如果沒有獲得者和制定者,你就無法做到這一點。有時候編制你可能需要的東西是明智的,而不是你現在需要的東西。

+0

對於某些類型,這種情況是現實的。對於其他人,他們不是。你能想到任何未來版本的'Point'可能在屬性獲取器或設置器中有用嗎?如果'Point'是一個具有* virtual *屬性的類,未來的派生類可能會添加有用的行爲,但是由於特定的'Point'實例不知道它們被用於什麼,並且預期會接受任何' 「X」和「Y」的Int32'值,我想不出任何未來的實現可能會增加。 – supercat 2013-06-04 21:07:22

19

理由三:

  1. 喜歡你可以將屬性不能覆蓋領域中的子類。
  2. 您可能最終需要更復雜的getter或setter,但如果它是一個字段,則更改它會破壞API。
  3. 公約。這就是它完成的方式。

我敢肯定還有更多的原因,我只是沒有想到。

在.net 3.x中,你可以使用自動屬性是這樣的:

public int Age { get; set; } 

,而不是老派的方式與自己宣佈你的私人領域是這樣的:

private int age; 

public int Age 
{ 
    get { return age; } 
    set { age = value; } 
} 

這使得就像創建一個字段一樣簡單,但沒有突破性變化問題(等等)。

+0

= 1:你在哪裏得到的字段不能被序列化? – 2009-08-14 12:38:08

+1

「您最終可能需要更復雜的getter或setter,但如果它是一個字段,更改它會破壞API。」 不是。 您可以安全地從:public int Joe; 至 private int _joe; 公衆詮釋喬 { 獲得{//做一些事情} 集合{//做一些事情}} 您可能需要改變很多內部參考的,但是,這並不破壞你的API。 – 2009-08-14 12:39:41

+0

@John Saunders這就是我讀過的......這是不是真的?它是真的嗎? – 2009-08-14 12:42:28

0

實際上,如果您使用的是Silverlight,您會意識到無法將字段設置爲靜態資源,因此您必須使用屬性(即使訪問const)。

我意識到,當我試圖聯合在複合制導(PRISM)中使用的區域名稱。

但是,這只是一種語言限制,除了static/const字段,我也會使用屬性。

0

這個想法是你不應該意外/無意中改變一個班級私人領域的價值。 當你使用get和set時,這意味着你有意和有意地改變了類私有域。

6

當您創建私有字段和簡單的公共財產名稱實際獲取和設置名稱字段值

public string Name 
{ 
    get { return name; } 
} 

,你到處使用這個屬性類,有一天外面你決定名稱這個類的屬性實際上是指姓氏字段(或者你想返回一個字符串「My name:」+ name),你只需要在裏面修改代碼屬性:

public string Name 
{ 
    get { return lastName; //return "My name: "+name; } 
} 

如果你在外面的代碼中使用公共領域無處不在,那麼你就必須改變lastName的無處不在,你使用它。

0

設置一個值轉換成私有字段只改變了場,但使他們的財產,你可以處理其它參數,例如,你可以設置一個值

 
private string _email; 
public string Email 
{ 
    get 
    { 
     return this._email; 
    } 
    set 
    { 
     this._email = value; 
     ReplaceList(); //** 
    } 
} 




+0

好吧,但他不需要做任何事情,只是返回_email。那麼,什麼是財產的原因?原因在於未來的使用。 – agnieszka 2009-08-14 12:40:07

2

這...取決於後調用的方法?

我總是用干將&制定者,因爲他們創造了這個快捷方式:

公衆詮釋美孚{獲得;組; }

在編譯時它被翻譯。現在你不可能喜歡它,但它在那裏,如果你想要看起來很花哨,你可以稍後再拼出來。

然而,公共,私人,受保護...這都是你想要調整數據的問題。我們大量使用繼承,這對我們來說是一種非常普遍的方法,所以只有孩子才能編輯某些屬性。

protected _foo; 
public Foo 
{ 
    get { return _foo; } 
} //lack of set intentional. 
-1

我不能相信,11分的答案,沒有人對此表示:

並非所有的私有字段應該暴露的公共屬性。你當然應該使用屬性來表達任何需要非私人性質的東西,但是你應該儘可能地保持私人空間的私密性。

+1

重讀這個問題 - 在這種情況下,我需要這些私人字段在課堂外可以訪問。當然,你不會公開每個領域或給每個領域的財產! – 2009-08-14 12:47:06

+0

實際上,這個問題並沒有說明你需要什麼,只是關於你看到的每個私人領域的公共財產。如果你的領域需要公共訪問,那麼他們不是私人領域,並且不符合你問的問題。請編輯該問題以清楚說明_your_代碼的內容,而不是您在「SO,codeproject.com」上看到的示例 – 2009-08-14 13:07:40

4

你必須在下列情況下使用性質:

  1. 當你需要的財產,以某種格式序列化數據。
  2. 當您需要覆蓋派生類中的屬性時。
  3. 當你用某種邏輯實現get和set方法。例如,當你實現Singleton模式。
  4. 當您從接口派生,其中聲明瞭屬性。
  5. 當您遇到與Reflection有關的特定問題時。
+2

您爲什麼認爲字段無法序列化? – 2009-08-14 13:08:20