2010-01-28 59 views
11

這是我一直在我的代碼中摔跤的東西。假設我們有以下代碼:在課堂內部時,最好稱其私人成員或其公共屬性?

public class MyClass { 
    private string _myVariable; 

    public string MyVariable { 
     get { return _myVariable; } 
     set { _myVariable = value; } 
    } 

    public void MyMethod() { 
     string usingPrivateMember = _myVariable; // method A 
     string usingPublicProperty = MyVariable; // method B 
    } 
} 

哪種方法更正確 - 方法A還是B?我總是對此感到t t不安。方法A看起來好像會更快一些,因爲在獲得實際變量之前,它不必訪問屬性。但是,方法B更安全,因爲如果MyVariable的getter獲取業務邏輯,那麼即使沒有當前的業務邏輯,您也可以始終調用它。

什麼是普遍的共識?

+0

和http://stackoverflow.com/questions/1545297/fields-vs-properties-for-private-class-variables – 2010-01-28 03:18:38

+1

感謝您找到那些!我試過搜索,但我想我沒有使用正確的關鍵字進行搜索。 – Amberite 2010-01-28 03:24:10

+1

SO搜索*仍*非常差,您是否嘗試過Google和'site:stackoverflow.com'? – Ash 2010-01-28 05:36:57

回答

12

使用該屬性。

我認爲該財產應該全權負責管理該領域。

有很多的實現在哪裏並不重要,但有很多地方它很重要 - 很多。另外,這可以有點痛苦追蹤,因爲它總是看起來沒錯。

你會錯誤地調用該屬性的次數比調用該字段的次數少得多,並且在那裏有這個規則的例外情況,請說明理由。

+0

使用該屬性的一個優點是您可以在每次讀取/寫入時設置一個斷點。這對於大型,陌生的代碼庫尤其有用。它允許您在調試器中跨越大塊代碼,但在修改屬性時仍會停止。非常便利。 – 2010-01-28 04:24:09

+0

當使用存根進行單元測試時,它也可能非常方便,因爲您可以在存根屬性上設置值,但不在私有成員上設置值。 – Jay 2010-01-28 04:31:45

1

這實際上取決於你正在訪問的屬性。考慮以下兩種情況:

方案1:你寫一個方法,以提供在類中的數據的共同行動:

// assume a hypothetical class Position 

public class Circle 
{ 
    private int _radius; 
    private int _xpos; 
    private int _ypos; 

    public int Radius { get { return _radius; } } 
    public Position Center { get { return new Position(_xpos, _ypos); } } 

    public bool PointInCircle(Position other) 
    { 
     return distance(this.Center, other) < this.Radius; 
    } 
} 

顯然PointInCircle的行爲應該是相同的,如果用戶執行它裏面的代碼。因此,使用公共屬性是有意義的。

場景2:您編寫了一個方法來操縱底層數據。序列化就是一個很好的例子。您會希望序列化底層數據成員,而不是由屬性訪問器返回的值。

1

取決於,如果你訪問屬性,可能會有'驗證'代碼被調用。

private int timeSinceLastPropertyAccess; 

public int TimeSinceLastPropertyAccess 
{ 
    get 
    { 
     // Reset timeSinceLastPropertyAccess to 0 
     int a = timeSinceLastPropertyAccess; 
     timeSinceLastPropertyAccess = 0; 
     return a; 
    } 
} 

您是否希望timeSinceLastPropertyAccess在您的課堂內使用時被重置?

+0

這是非常糟糕的吸氣劑設計。獲取方法不應該修改狀態。 – 2010-01-28 03:17:51

+0

太過真實,但它表明如果使用吸氣劑可能會產生不希望的效果。 – PostMan 2010-01-28 03:23:23

+2

考慮一下,我們正在討論在具有這些屬性的同一個類中。因此,吸氣劑是否蹩腳足以產生重大副作用完全是您自己的選擇。 – 2010-01-28 03:24:37

1

只是再增加一件事,你的例子只問了getters。另一半是二傳手。

有時你會希望對象使用setters,有時你會希望它繞過它們,只是分配底層字段。

例如,假設您有一個名爲IsModified的屬性。當對象被修改時,它會告訴你什麼。如果將不同的值分配給其中一個基礎字段,您可以讓所有設置者將其翻轉爲true。

現在,如果您正在補充該對象(從數據庫或其他地方加載),那麼你不會想要IsModified集。因爲,坦率地說,它還沒有被修改。因此,在該方法中,您使用基礎字段名稱,但在所有其他使用屬性設置器的方法中。

0

它取決於,你想做什麼屬性?私人/公共並不重要,就像調用函數一樣。

事實上,您確實只是設置了一個「函數」,以期在訪問或更改值時必須執行某些操作。

這樣做的問題是,您可能會發現您希望在某處執行某項操作,而在其他位置執行該操作時需要執行另一項操作,因此您仍然需要更改所有的「調用'在其中一個地方。

問題的實質是,如果通過剛剛通過變量的屬性訪問該變量 - 甚至是私有類函數 - 都會這樣做,爲什麼還要擁有該屬性?爲什麼不只是創建名爲'MyVariable'的變量,那麼如果你發現你想改變/訪問時想做些什麼,只需創建另一個名爲_MyVariable的變量或其他東西,然後將MyVariable改爲_MyVariable的屬性。

你應該認爲屬性就像你用來寫入的accessor()和mutator()函數一樣,它們的訣竅是,如果你發現你想在某個變量被訪問時做一些代碼'你必須改變所有對該變量的調用來改用訪問器(調用一個函數,而不是訪問一個成員變量),這就是爲什麼你要創建'默認'訪問器和matadors,以防萬一。正如我上面所說的,你沒有與c#和屬性的問題(除非在一個跛腳的情況下,你不能寫信給成員的子成員,如果它的屬性...爲什麼??)

相關問題