2009-03-02 102 views
104

快速問題:您何時決定使用屬性(在C#中)以及何時決定使用方法?屬性vs方法

我們正在忙着進行這場辯論,並且發現了一些我們是否應該使用財產或方法值得商榷的領域。一個例子是這樣的:

public void SetLabel(string text) 
{ 
    Label.Text = text; 
} 

在這個例子中,Label是一個ASPX頁面上的控件。是否有一個原則可以決定是否將此作爲一種方法或一種財產。

我會接受最通用最全面的答案,但這也涉及到我給出的例子。

+2

-1這個問題已經被問及之前回答:http://stackoverflow.com/questions/164527/exposing-member-objects-as-properties-or-methods-in-net – Element 2009-03-02 08:36:46

+0

方法/字段/屬性利弊會引起長時間的辯論;一些常用的屬性:當你想要私人/受保護的領域,但同時你想暴露他們。另一個用途是不僅有語句,而且還有表達式(如果你喜歡,可以採取行動),即使if()檢查(按照MSDN)。但這很棘手,因爲用戶並不總是知道訪問變量(屬性)後的處理成本(即代碼不可用),並且出於嚴格的原因必須對該屬性進行基準測試。哦,還有一個「獎勵」,你不能用屬性指針。 – mireazma 2016-11-28 13:14:53

回答

111

從設計準則的開發類庫Choosing Between Properties and Methods部分:

一般來說,方法代表操作和性能表現數據。屬性意味着像字段一樣使用,這意味着屬性不應該在計算上覆雜或產生副作用。如果它沒有違反以下準則,請考慮使用屬性而不是方法,因爲經驗較少的開發人員發現屬性更易於使用。

+3

雖然我很同意這一點,但我不認爲關於副作用的部分是正確的。例如,「顏色」通常是一個對象的屬性,它有明顯的副作用(改變對象的顏色)。更改屬性具有更改對象狀態的明顯副作用。 – 2009-03-02 08:48:28

47

是的,如果您所做的只是獲取和設置,請使用屬性。

如果您正在做一些可能影響多個數據成員的複雜操作,則更合適。或者如果你的getter使用參數,或者你的setter的參數不止一個值。

中間是一條灰色區域,線條可能有點模糊。沒有硬性規定,不同的人有時會不同意某種東西是財產還是方法。重要的是要與你的如何做(相對)一致(或者你的團隊如何做)。

它們在很大程度上是可以互換的,但是一個屬性向用戶表明實現相對「簡單」。哦,語法更清潔一點。

一般來說,我的理念是,如果您開始編寫一個以get或set開頭並且分別佔用零個或一個參數的方法名稱,那麼它是屬性的主要候選項。

+0

我認爲這應該是被接受的答案。 – 2016-05-07 23:13:23

+0

最低票數。這是不正確的。 getter/setter代碼的複雜性被封裝在getter/setter代碼中。它有多複雜,根本不相關,也不會影響多個數據成員。確實,非標準或多個參數需要一種方法,但否則這個答案是不準確的。 – Hal50000 2016-11-10 23:18:05

+0

第一句解釋所有。布拉沃。 – SWIIWII 2017-09-23 20:58:41

3

我更喜歡使用屬性添加/設置方法與參數。如果參數更多,請使用方法。

3

屬性應該只是簡單的設置並獲得一個襯墊。任何更多,它應該真的被轉移到一種方法。複雜的代碼應該總是在方法中。

12

如果你正在設置對象的實際屬性,那麼你使用一個屬性。

如果您正在執行任務/功能,那麼您可以使用一種方法。

在你的例子中,它是一個確定的屬性被設置。

但是,如果您的功能是AppendToLabel,那麼您將使用一種方法。

2

屬性是非常好的,因爲它們可以在Visual Studio的可視化設計器中訪問,只要它們可以訪問。

他們使用的是你只是設置和獲取,也許一些驗證,不訪問大量的代碼。要小心,因爲在驗證過程中創建複雜對象並不簡單。

其他方法是首選的方法。

它不只是關於語義。在視覺工作室視覺設計師中使用不合適的屬性開始出現怪異現象。

例如,我在一個類的屬性中獲取配置值。配置類實際上會打開一個文件並運行一個sql查詢來獲取該配置的值。這在我的應用程序中導致了問題,即配置文件被Visual Studio本身打開和鎖定,而不是我的應用程序,因爲它不僅僅是讀取,而是寫入配置值(通過setter方法)。爲了解決這個問題,我只好把它改成一個方法。

3

我只使用變量訪問屬性,即獲取和設置單個變量,或獲取和設置控件中的數據。只要需要/執行任何類型的數據操作,我就使用方法。

7

你只需要看看這個名字......「屬性」。這是什麼意思?字典在很多方面對它進行了定義,但在這種情況下,「一個事物的基本或獨特的屬性或質量」最適合。

想想行動的目的。事實上,你是否在改變或檢索「一個基本或獨特的屬性」?在你的例子中,你正在使用一個函數來設置一個文本框的屬性。這似乎有點愚蠢,不是嗎?

屬性確實是函數。他們都編譯得到XXX()和setXXX()。它只是將它們隱藏在句法糖中,但它爲過程提供了語義含義的糖。

想想像屬性這樣的屬性。一輛汽車有很多屬性。顏色,MPG,模型等。並非所有的屬性都是可封閉的,有些屬於可計算的。

同時,一個方法是一個動作。 GetColor應該是一個屬性。 GetFile()應該是一個函數。另一個經驗法則是,如果它不改變對象的狀態,那麼它應該是一個函數。例如,CalculatePiToNthDigit(n)應該是一個函數,因爲它實際上並不改變它所連接的Math對象的狀態。

這可能是漫不經心的,但它確實歸結爲決定你的對象是什麼,以及它們代表什麼。如果你不能確定它應該是一個屬性還是功能,那麼可能哪個不重要。

8

語義屬性是對象的屬性。 方法是你的對象的行爲。

標籤是一個屬性,使它成爲一個屬性更有意義。

在面向對象編程方面,您應該清楚地瞭解什麼是行爲的一部分,什麼是屬性。

車{顏色,型號,品牌}

汽車有顏色,型號,因此品牌屬性,它沒有任何意義有一種方法的setColor或則setModel因爲symantically我們不問車設置自己的顏色。

因此,如果您將屬性/方法案例映射到真實生活對象或從語義視角查看它,那麼您的混淆將會真正消失。

12

屬性是一種從對象注入或檢索數據的方法。它們創建一個對類中的變量或數據的抽象。它們類似於Java中的getter和setter。

方法封裝操作。

在一般情況下,我使用屬性來暴露數據的單個位,或類的小計算,如銷售稅。這是從購物車中的物品數量及其成本中獲得的。

我在創建操作時使用方法,如從數據庫中檢索數據。任何具有移動部件的操作都是方法的候選人。

在您的代碼示例中,我將它包裝在一個財產,如果我需要訪問它之外它含有類:

public Label Title 
{ 
    get{ return titleLabel;} 
    set{ titleLabel = value;} 
} 

設置文本:

Title.Text = "Properties vs Methods"; 

如果我只是設置標籤的文本屬性這是我該怎麼做的:

public string Title 
{ 
    get{ return titleLabel.Text;} 
    set{ titleLabel.Text = value;} 
} 

設置文本:

Title = "Properties vs Methods"; 
2

作爲設計屬性表示數據或類對象的屬性,而方法是類對象的動作或行爲。

在.NET中,世界上有使用性質等方面的影響:

  • 屬性在數據綁定使用,而的get_/set_方法都沒有。
  • XML序列化用戶屬性作爲自然的服務機制。
  • 屬性訪問PropertyGrid控制和實習生ICustomTypeDescriptor,如果您正在編寫自定義庫,它可以有效地使用。
  • 屬性由Attributes控制,人們可以明智地使用它來設計Aspect Oriented軟件。

誤解(恕我直言)有關屬性用法:

  • 用來揭露小算了一筆賬:ControlDesigner.SelectionRules的獲取塊運行到72行!
  • 用於公開內部數據結構:即使某個屬性沒有映射到內部數據成員,也可以將其用作屬性(如果該屬性是您的類的屬性)。 Viceversa,即使它的類屬性屬性不可取,也可以返回類似數據成員的數組(而不是方法用於返回成員的深層副本。)

在這裏的例子也可以寫成,提供更多的商業意義:

public String Title 
{ 
    set { Label.Text = text; } 
} 
7

通過MSDN搜索,我發現Properties vs Methods提供用於創建方法的一些偉大的準則參考:

  • 該操作是一種轉換,如Object.ToString
  • 該操作非常昂貴,您希望與 用戶溝通,他們應該考慮高速緩存 的結果。
  • 使用get訪問器獲取屬性值會產生可觀察的 副作用。
  • 連續兩次調用成員會產生不同的結果。
  • 執行順序很重要。請注意,可以按任意 的順序設置和檢索類型的屬性 。
  • 該成員是靜態的,但返回一個可以更改的值。
  • 該成員返回一個數組。返回數組的屬性可能是非常容易讓人誤解的 。通常是 需要返回 內部陣列的副本,以便用戶不能更改內部狀態 。這與 耦合在一起,事實上用戶可以容易地將 假設爲索引屬性, 導致低效的代碼。
-1

我來自java一個我用get .. set ..方法一段時間。

當我編寫代碼時,我不會問自己:「訪問這些數據很簡單,還是需要一個繁重的過程?」 因爲事情可以改變(今天回顧這個屬性很簡單,tomonrow可能需要一些或繁重的過程)。

今天我有一個方法SetAge(int age)tomonrow我也會用方法SetAge(date birthdate)來計算使用出生日期的年齡。

我很失望,編譯器在get和set中轉換屬性,但不認爲我的Get ...和Set ..方法是一樣的。

-1

這裏是一個很好一套指引何時使用性能相方法從Bill Wagner

  • 使用一個屬性當所有這些都是真的: 的干將應該是簡單的,因此不太可能拋出異常。請注意,這意味着沒有網絡(或數據庫)訪問。要麼可能會失敗,因此會拋出異常。
  • 他們不應該彼此依賴。請注意,這將包括設置一個屬性並影響另一個屬性。(例如,設置了名字屬性將影響由第一名+姓性質隱含了這種相關性的只讀FullName屬性)
  • 他們應該以任何順序
  • 吸氣不具有可觀察到的是設定副作用請注意,本指南並不排除某種形式的物業惰性評估。
  • 該方法必須始終立即返回。 (請注意,這排除了進行數據庫訪問調用,Web服務調用或其他類似操作的屬性)。
  • 如果成員返回數組,則使用方法。
  • 重複調用getter(無中介代碼)應返回相同的值。
  • 重複調用setter(具有相同的值)的調用應該不會影響單個調用。

  • get不應該返回對內部數據結構的引用(請參閱第23項)。一種方法可以返回一個深層副本,並可以避免這個問題。

*從我的答案採取重複問題。

3

屬性的另一大優點是在調試過程中可以在Visual Studio中看到屬性的值。