2008-09-17 61 views
3

我有一個字符串屬性的類,實際上是用分隔符連接的幾個字符串。「代理屬性」是不錯的風格?

我想知道,如果是好的形式有代理性質是這樣的:

public string ActualProperty 
{ 
    get { return actualProperty; } 
    set { actualProperty = value; } 
} 

public string[] IndividualStrings 
{ 
    get { return ActualProperty.Split(.....); } 
    set 
    { 
      // join strings from array in propval .... ; 
      ActualProperty = propval; 
    } 
} 

有我忽略任何風險?

回答

0

那麼我會說你的「設置」是高風險的,如果有人不知道他們必須通過一個已經加入的值序列,或者你上面的例子可能沒有這樣做。如果字符串已經包含分隔符 - 你會中斷。

根據這個屬性的使用頻率,我確定性能不是很好。

1

定義「好」。它不應該中斷(除非你沒有妥善保證傳遞給Split()的分隔符絕不允許在單獨的字符串本身中),但是如果IndividualStrings的訪問頻率比ActualProperty更頻繁,那麼你最終會更頻繁地解析actualProperty比你應該。當然,如果反過來是真的,那麼你做得很好......如果兩者都經常被調用,以致任何不必要的解析或連接都是不可接受的,那麼只需存儲兩者並在該值改變時重新解析。

0

我不確定這個設計的好處是什麼。我認爲這種拆分在擴展方法中會更好。至少,我會移除IndividualStrings屬性上的setter,或將其移入兩個方法:string [] SplitActualProperty()和void MergeToActualProperty(string [] parts)。

2

將兩個可設置的屬性鏈接在一起在我看來是不好的juju。切換到顯式的get/set方法而不是屬性,如果這真的是你想要的。代碼具有非明顯的副作用,幾乎總是會在以後出現。儘可能保持簡單和直接的事情。另外,如果你有一個屬性是一個包含子字符串的格式化字符串,它看起來像你真正想要的是一個單獨的結構/類的屬性,而不是濫用原始類型。

2

看起來數組是真實的數據,而單字符的東西是一個方便。這很好,但我想說的是諸如序列化和成員克隆這樣的東西,它們將獲取和設置兩個可寫屬性。

我想我會;

  • 保持陣列作爲屬性
  • 提供GetJoinedString(string seperator)方法。
  • 提供了一種SetStrings(string joined, string seperator)Parse(string joined, string seperator)方法。

實際上,字符串中的分隔符不是類的一部分,而是一個短暫的細節。明確引用它,例如,一個CSV應用程序可以傳遞一個逗號,其中製表符分隔的應用程序可以傳遞一個製表符。它會讓您的應用更易於維護。此外,它消除了爲相同的實際數據設置兩個getter和setter的令人討厭的問題。

1

屬性意圖是一類非常簡單的成員;獲取或設置屬性的值應該被認爲是微不足道的操作沒有顯著的副作用

如果設置屬性會導致比分配財產的其他更改類的公共價值觀,這比一個基本的分配更加顯著,並可能不再是一個非常適合的屬性。

「複雜」的屬性是危險的,因爲它是從呼叫者的預期打破。屬性被解釋爲字段(帶有副作用),但作爲字段您希望能夠分配一個值,然後稍後檢索該值。通過這種方式,調用者應該能夠分配給多個屬性並在稍後再次檢索它們的值。

在你的榜樣,我不能一個值分配給兩個屬性檢索它們;一個值會影響另一個值。這打破了財產的基本期望。如果您創建一個方法將值同時分配給兩個屬性,並使這兩個屬性都是隻讀的,則更容易瞭解設置值的位置。

另外,順便說一句:

它通常被認爲是不好的做法,從屬性返回臨時數組。數組可能是不可變的,但它們的內容不是。這意味着你可以改變數組中的一個值,這個值將會繼續與對象一起存在。

例如:

YourClass i = new YourClass(); 
i.IndividualStrings[0] = "Hello temporary array!"; 

這段代碼看起來像它在IndividualStrings特性改變的值,但實際上該陣列由屬性創建,而不是在任何地方分配的,所以陣列和變化將下降立即超出範圍。

public string ActualProperty { get; set; } 

public string[] GetIndividualStrings() 
{ 
    return ActualProperty.Split(.....); 
} 

public void SetFromIndividualStrings(string[] values) 
{ 
    // join strings from array .... ; 
}