【问题标题】:C# - Code Analysis 2227 ConfusionC# - 代码分析 2227 困惑
【发布时间】:2011-04-05 23:50:50
【问题描述】:

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

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 - 是的,我绑定了 XAML。

标签: c# code-analysis


【解决方案1】:

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

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

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

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

【讨论】:

  • 谢谢。这正是我应该做的。
【解决方案2】:

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

这只是一个建议:)

在这种情况下,你会使用:

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

请注意,尽管此 不会触发更改事件...您可能希望改用 ObservableCollection。

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

【讨论】:

    【解决方案3】:

    您想要另一个实例与RecipeList 混淆吗?通常,除了拥有该集合的实例之外,我不会让任何东西更改我的集合实例。你可以做到private

    【讨论】:

      【解决方案4】:

      MSDN description 相当清楚:

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

      如果您班级的客户可以将列表更改为完全不同的食谱列表,那将不是很好的 OO。这违反了encapsulation

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-07-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-10-05
            • 1970-01-01
            相关资源
            最近更新 更多