C# - 代码分析 2227 混淆

5

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

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更改为只读。有人能告诉我为什么吗?


有什么东西使用了setter吗? - Douglas
@Douglas - 是的,我已经将XAML绑定到它了。 - Hosea146
6个回答

3

List<T> 对象上添加公共 setter 是危险的。通过将 setter 改为私有来消除此警告:

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

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

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

2

我认为它的意思是通常情况下,集合属性本身不应该是可变的 - 更常见的是集合本身是可变的,并且只能通过设置器进行访问。

但这只是一个建议 :)

在这种情况下,您可以使用:

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

请注意,这样做虽然不会触发更改事件...但是您可能希望使用ObservableCollection代替。
这也意味着任何人都可以更改配方列表的内容...您确定要这样吗?另一种选择是公开一个ReadOnlyCollection 属性或类似的东西,并仅在自己的类内进行更改。这取决于您尝试做什么。

1

你想让另一个实例来搞乱RecipeList吗?通常情况下,我不允许任何东西改变我的集合实例,除了拥有该集合的实例。你可以将其设置为private


1

MSDN描述相当清晰:

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

如果您的类的客户端可以将列表更改为完全不同的食谱列表,那么它就不是良好的面向对象编程。这违反了封装的原则。

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


0

我不认为代码有任何违法之处,但通常不会为集合类型属性设置公共设置器。你的私有RecipeSearch方法应该只设置_recipeList并引发事件,或者你可以将_recipeList本身作为受保护的属性处理事件。


0

允许以两种方式(通过其自身的AddRemove方法以及整个列表实例)改变列表属性,会给使用该属性的人造成模糊的接口。这会混淆责任并创建更大的技术债务/维护开销。

相反,通常最好将这些问题分开处理,使属性提供对列表单个实例的访问。如果必须更改列表实例,则使用单独的机制可以更清楚地表明与属性交互的操作和更改该属性指向的列表实例的操作是不同的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接