C# - 代码分析 2227 混乱

发布于 2024-10-29 19:28:32 字数 568 浏览 1 评论 0原文

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

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 警告:通过删除设置器将 RecipeList 更改为只读。谁能告诉我为什么?

I have a class property that looks as follows:

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

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

In another method I have the following which references the property above.

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

Code Analysis is issuing a CA 2227 warning: Change RecipeList to be read-only by removing the setter. Could anyone tell me why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

绝情姑娘 2024-11-05 19:28:32

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

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

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

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

Adding a public setter on a List<T> object is dangerous. You can eliminate this warning by making your setter private:

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

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

This will still allow your class to change this method, but no external source.

晒暮凉 2024-11-05 19:28:32

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

不过,这只是一个建议:)

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

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

请注意,这不会触发更改事件...您可能想改用 ObservableCollection。

这也意味着任何人都可以更改食谱列表的内容...您确实想要这样吗?另一种选择是公开 ReadOnlyCollection属性或类似的内容,并且仅在您自己的类中进行更改。这实际上取决于您想要做什么。

I think it's suggesting that usually collection properties themselves shouldn't be mutable - it's more common for the collection to be mutable, and just available via a setter.

It's only a suggestion though :)

In this case you'd use:

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

Note that this won't fire the change event though... you might want to use ObservableCollection instead.

This will also mean that anyone can change the contents of the recipe list... do you definitely want that? Another alternative is to expose a ReadOnlyCollection<T> property or something like that, and only make changes within your own class. It really depends what you're trying to do though.

月竹挽风 2024-11-05 19:28:32

您想要另一个实例来扰乱 RecipeList 吗?一般来说,除了拥有该集合的实例之外,我不会让任何东西更改我的集合实例。您可以将其设为私有

Do you want another instance messing with RecipeList? Generally, I don't let anything change my collection instances except the instance that owns the collection. You could make it private.

眼角的笑意。 2024-11-05 19:28:32

MSDN 描述相当清楚:

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

如果你的班级的客户可以将列表更改为完全不同的食谱列表,那么面向对象就不太好了。这是反对封装的。

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

The MSDN description is fairly clear:

A writable collection property allows
a user to replace the collection with
a completely different collection

It wouldn't be good OO if the client of your class could change the list to be a completely different list of Recipes. That is against encapsulation.

Ensuring the clients just add or remove items is what you probably want to do.

じ违心 2024-11-05 19:28:32

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

I don't think there's anything illegal about the code, but it's common practice to have no public setter for collection type properties. Your private RecipeSearch method should just set _recipeList and raise the event, or you could make _recipeList itself a protected property that handles the event.

2024-11-05 19:28:32

允许列表属性以两种方式发生变化(通过它自己的 AddRemove 方法以及整个列表实例)会为使用该属性的人创建一个不明确的接口。这会混淆职责并产生更大的技术债务/维护开销。

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

Allowing the list property to be mutated in two ways (via it's own Add and Remove methods and the list instance as a whole) creates an ambiguous interface to those who consume that property. This confuses responsibilities and creates a larger technical debt/maintenance overhead.

Instead, it is often better practise to separate these concerns so that the property provides access to a single instance of the list. If the list instance must be changeable, a separate mechanism for doing so makes it much clearer that the action of interacting with the property and the action of changing which list instance that property points to are distinct.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文