2011-04-05 78 views
5

我有一個類屬性,如下所示:C# - 代碼分析2227困惑

public List<Recipe> RecipeList 
{ 
    get { return this._recipeList; } 

    set 
    { 
     this._recipeList = value; 
     OnPropertyChanged("RecipeList"); 
    } 
} 

在另一種方法我有引用上面的屬性如下。

private void RecipeSearch() 
{ 
      this.RecipeList = RecipeManagerService.SearchByUnit(SearchCriteria) 
           .Where(recipe => recipe.IsApproved == true && !recipe.IsHidden).ToList(); 
} 

代碼分析發出CA 2227警告:通過刪除setter將更改RecipeList爲只讀。有誰能告訴我爲什麼?

+0

是否有任何東西使用setter? – Douglas 2011-04-05 15:45:49

+0

@Douglas - 是的,我有XAML綁定它。 – Hosea146 2011-04-05 15:46:42

回答

3

List<T>對象上添加公共setter是很危險的。您可以通過您的二傳手私人消除這樣的警告:

public List<Recipe> RecipeList 
{ 
    get { return this._recipeList; } 

    private set 
    { 
     this._recipeList = value; 
     OnPropertyChanged("RecipeList"); 
    } 
} 

這仍然可以讓你的類來更改這個方法,但是沒有外部來源。

+0

謝謝。這正是我應該做的。 – Hosea146 2011-04-05 15:51:21

1

你想要另一個實例與RecipeList搞混嗎?通常,我不會讓任何東西改變我的集合實例,除了擁有集合的實例。你可以製作它private

2

我認爲這是暗示通常集合屬性本身不應該是可變的 - 集合是可變的,並且通過setter可用。

這只是一個建議,但:)

在這種情況下,你會使用:

RecipeList.Clear(); 
RecipeList.AddRange(RecipeManagerService 
           .SearchByUnit(SearchCriteria) 
           .Where(r => r.IsApproved && !r.IsHidden)); 

注意這不會火更改事件雖然...你可能想改用ObservableCollection。

這也意味着任何人可以改變配方列表的內容......你一定要這樣嗎?另一種選擇是公開一個ReadOnlyCollection<T>屬性或類似的東西,只在你自己的類中進行更改。這真的取決於你想要做什麼。

0

我不認爲代碼有任何不合法的地方,但是對於集合類型屬性沒有公共setter是常見的做法。您的私人RecipeSearch方法應該只設置_recipeList並引發該事件,或者您可以讓_recipeList本身成爲處理事件的受保護屬性。

1

MSDN description是相當清楚的:

可寫的集合屬性允許 用戶與 更換收集了完全不同的集合

它不會是好的OO如果客戶端你的班級可以將列表更改爲完全不同的食譜列表。這是針對encapsulation

確保客戶只需添加或刪除項目是您可能想要做的。

0

允許列表屬性以兩種方式進行變異(通過它自己的AddRemove方法和列表實例作爲一個整體)爲使用該屬性的人員創建了一個模糊的接口。這混淆了責任,造成了更大的技術債務/維護費用。

相反,將這些問題分開以便該屬性可以訪問列表的單個實例通常是更好的做法。如果列表實例必須是可更改的,那麼一個單獨的機制可以更清楚地表明與屬性交互的操作以及更改屬性指向的不同列表實例的操作。