C# – 代码分析2227混淆

我有一个类属性,如下所示:

public List 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更改为只读。 谁能告诉我为什么?

List对象上添加公共setter是危险的。 您可以通过将您的setter设为私有来消除此警告:

 public List RecipeList { get { return this._recipeList; } private set { this._recipeList = value; OnPropertyChanged("RecipeList"); } } 

这仍然允许您的类更改此方法,但不允许外部源。

我认为这表明通常集合属性本身不应该是可变的 – 集合更常见的是可变,并且只能通过setter获得。

这只是一个建议虽然:)

在这种情况下,您将使用:

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

请注意,这不会触发更改事件…您可能希望使用ObservableCollection。

这也意味着任何人都可以改变食谱清单的内容……你真的想要吗? 另一种方法是公开ReadOnlyCollection属性或类似的东西,只在你自己的类中进行更改。 这真的取决于你想要做的事情。

你想要另一个实例搞乱RecipeList吗? 通常,除了拥有该集合的实例之外,我不会让任何更改我的集合实例。 你可以把它变成private

MSDN描述相当清楚:

可写集合属性允许用户使用完全不同的集合替换集合

如果您的class级的客户可以将列表更改为完全不同的食谱列表,那将不是一件好事。 这是反对封装 。

确保客户只是添加或删除项目是您可能想要做的。

我不认为代码有任何违法行为,但通常的做法是没有集合类型属性的公共setter。 您的私有RecipeSearch方法应该只设置_recipeList并引发事件,或者您可以使_recipeList本身成为处理事件的受保护属性。

允许以两种方式(通过它自己的AddRemove方法以及整个列表实例)对列表属性进行变异,从而为使用该属性的人创建一个模糊的界面。 这会使责任混乱并产生更大的技术债务/维护费用。

相反,通常更好的做法是将这些关注点分开,以便属性提供对列表的单个实例的访问。 如果列表实例必须是可更改的,那么这样做的单独机制使得与属性交互的操作以及更改属性指向的列表实例的操作更加清晰。