【问题标题】:FxCop CA2227 warning and ReadOnlyCollection<T>FxCop CA2227 警告和 ReadOnlyCollection<T>
【发布时间】:2010-04-30 08:13:10
【问题描述】:

在我的 VS2008 SP1、.NET 3.5 SP1 项目中,我有包含不同属性的不同类。 我经常使用 C#3.0 自动属性。

其中一些属性需要是集合。因为我想让它变得简单,所以我将ReadOnlyCollection&lt;T&gt; 用于这些属性。

我不想使用IEnumerable&lt;T&gt;,因为我想随机访问元素。

我使用代码分析(FxCop 规则)并收到 CA2227 警告。

我不明白为什么ReadOnlyCollection&lt;T&gt; 应该有一个 set 方法,而它不能被改变...... set 方法只能做属性可以做的事情。

例子:

using System.Collections.ObjectModel;

namespace CA2227
{
    public class MyClass
    {
        public ReadOnlyCollection<int> SomeNumbers { get; set; }
    }
}

CA2227:Microsoft.Usage:通过删除属性设置器将“MyClass.SomeNumbers”更改为只读。 C:\Users...\Visual Studio 2008\Projects\CA2227\MyClass.cs 7 CA2227

【问题讨论】:

    标签: c#-3.0 code-analysis fxcop visual-studio-2008-sp1 readonly-collection


    【解决方案1】:

    ReadOnlyCollection 无法更改,但是没有理由不能更改具有类型为 ReadOnlyCollection 的 setter 的属性以引用不同的 ReadOnlyCollection。如果您希望 SomeNumbers 属性是不可变的,那么它需要既是只读类型,又要有一个非公共的 setter。

    编辑

    如果您确信自己想要什么,那么尽管 FxCop 警告您是正确的,但您对警告感到满意。如果你想摆脱它,那么在那个时候包含一个SuppressMessage 属性——只要你在构建之前还在项目属性中定义了一个 CODE_ANALYSIS 常量,FxCop 就会尊重这个属性,而不是发出那个特定的警告那个特殊的场合。

    【讨论】:

    • 我希望能够更改属性的值。我不想收到 CA2227 警告。我还想了解为什么会收到 CA2227 警告以及是否应该以不同的方式编写代码。
    • 好吧,归根结底,这是一个警告,您正在做的事情不寻常并且可能不正确。如果您确信自己是对的 - 请查看我的编辑...
    • 我不相信。我想了解为什么我会收到 ReadOnlyCollection 而不是 IEnumerable 的警告。
    【解决方案2】:

    阻止对集合内容的更改而不阻止对集合本身的更改是相当奇怪的。如果您希望能够在您的类中设置集合,同时保留使用自动属性,您可以使用私有设置器。例如:

    public ReadOnlyCollection<int> SomeNumbers { get; private set; }
    

    【讨论】:

    • 为什么这么奇怪?为什么设置 IEnumerable (也不能修改)并不奇怪并且不提供 CA2227?我希望二传手是公开的。我喜欢使用对象初始化器——它不适用于私有设置器。
    • 允许设置 IEnumerable 属性也很不寻常,但至少这样做的意图是相当清楚的,并且类实现者应该知道其中的含义。我想人们可能会就 ReadOnlyCollection 提出相同的争论,但是当前编写的 FxCop 规则不会检查您公开的 ICollection 或 ICollection 实现。 [在下一条评论中继续]
    • 我怀疑您的代码对于真正的“公共”使用可能并不安全。除非您愿意投资检查是否允许随时调用 setter 不会导致意外的副作用,否则您可能希望将 setter 可见性降低到内部,这样可以在大多数情况下消除 FxCop 违规。
    • 我很确定设置 ReadOnlyCollection 或不会导致无法通过设置 IEnumerable 引起的意外副作用。
    【解决方案3】:

    考虑使用

    public class MyClass
    {
        public IReadOnlyList<int> SomeNumbers { get; set; }
    }
    

    ReadOnlyCollection = http://msdn.microsoft.com/en-us/library/ms132474(v=vs.110).aspx

    IReadOnlyList = http://msdn.microsoft.com/en-us/library/hh192385(v=vs.110).aspx

    ReadOnlyCollection 的问题在于它仍然从 ICollection 继承,并且仍然具有 .Add,尽管文档说它会抛出 - http://msdn.microsoft.com/en-us/library/cc672239(v=vs.110).aspx

    【讨论】:

      猜你喜欢
      • 2014-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-19
      • 2012-01-26
      • 1970-01-01
      • 2011-03-02
      相关资源
      最近更新 更多