c# -代码分析2227混淆

本文关键字:2227 混淆 代码 | 更新日期: 2023-09-27 17:49:19

我有一个类属性,看起来像这样:

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();
}

Code Analysis发出CA 2227警告:通过删除setter将RecipeList更改为只读。有人能告诉我为什么吗?

c# -代码分析2227混淆

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

public List<Recipe> 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));

注意这个不会触发change事件。你可能需要使用ObservableCollection。

这也意味着任何人都可以更改食谱列表的内容…你真的想要吗?另一种选择是公开ReadOnlyCollection<T>属性或类似的东西,并且只在您自己的类中进行更改。这取决于你想做什么

你想要另一个实例干扰RecipeList吗?一般来说,我不会让任何东西改变我的集合实例,除了拥有集合的实例。可以改成private

MSDN描述相当清晰:

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

如果类的客户端可以将列表更改为完全不同的Recipes列表,这将不是一个好的OO。这是违反封装的。

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

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

允许list属性以两种方式(通过它自己的AddRemove方法以及作为一个整体的list实例)进行突变,这会给使用该属性的人创建一个模糊的接口。这会混淆职责,并产生更大的技术债务/维护开销。

相反,分隔这些关注点通常是更好的做法,以便该属性提供对列表的单个实例的访问。如果列表实例必须是可更改的,那么一个单独的机制可以使与属性交互的行为和更改属性指向的列表实例的行为是不同的。