C#CA2104 - 自动代码分析不喜欢静态只读可变类型

时间:2009-03-27 07:24:46

标签: c# visual-studio-2008 code-analysis

我有一个这样的代码:

public abstract class Base
{
    // is going to be used in deriving classes
    // let's assume foo is threadsafe
    protected static readonly Foo StaticFoo = new Foo();
}

Visual Studio 2008的代码分析会弹出以下消息:

  

CA2104 : Microsoft.Security : Remove the read-only designation from 'Base.StaticFoo' or change the field to one that is an immutable reference type. If the reference type 'Foo' is, in fact, immutable, exclude this message.

我的设计是否存在本质上的缺陷,或者我可以在源代码中添加[SuppressMessage]吗?

3 个答案:

答案 0 :(得分:8)

问题在于它给出了错误的印象 - 它使得它看起来像值无法改变,而实际上它只是 field 值无法改变,而不是对象。我认为代码分析在这里过于谨慎 - 有很多地方你可能想要一个存储在只读字段中的可变类型,特别是如果它是私有的,在静态初始化程序中初始化然后从不在代码中变异。

虽然该字段受到保护,但派生类滥用它的风险更大。我个人认为我的所有领域都是私人的。另一方面,我不知道你的代码 - 可能是你已经权衡了可能性,并认为这是正确的做法。

如果Foo确实是线程安全的,那么除了由于该字段是只读的事实给出的不可变性的一般印象之外,不用担心。我将禁用该行的警告,并添加注释以强调该对象是可变的,即使该字段是只读的。

答案 1 :(得分:3)

Foo类型是不可变的吗?

如果没有,你打算只使用这一个Foo对象,但是能够改变它的属性吗?如果是这种情况,则警告只是说readonly关键字具有误导性。没有编译错误 - 对象的引用是只读的,这是您向编译器声明的内容。但是,您向其他开发人员声明的是,StaticFoo是只读的,这意味着它永远不会改变。

所以,你可以选择,正如它所说的那样。要消除此警告,请删除readonly keywoard,或添加SuppressMessage属性。或者,查看代码的设计。将Foo作为单例模式实现更合适吗?

答案 2 :(得分:1)

警告告诉您,readonly修饰符仅适用于引用本身。如果Foo是引用类型,则Foo实例的状态可能仍会被修改,除非您确保Foo是不可变的。

在另一个节点上,这样的静态可能会在单元测试代码时给你带来各种各样的问题,所以如果这对你很重要,你可能想看看其他方法来实现你的目标。试图做。