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

C#CA2104-自动代码分析不喜欢静态只读可变类型,c#,visual-studio-2008,code-analysis,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:从'Base.S

我有这样一个代码:

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:从'Base.StaticFoo'中删除只读指定,或将字段更改为不可变引用类型。如果引用类型“Foo”实际上是不可变的,则排除此消息。


我的设计本身是否有缺陷,或者我是否可以在源代码中添加
[SuppressMessage]

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


在另一个节点上,当涉及到代码的单元测试时,这样的静态可能会给您带来各种各样的问题,因此,如果这对您很重要,您可能会想看看其他方法来实现您正在尝试做的事情

Foo类型是不可变的吗

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


所以,正如它所说,你有一个选择。要消除此警告,请删除readonly键盘或添加SuppressMessage属性。或者,看看代码的设计。例如,将Foo实现为单例模式是否更合适?

问题在于,它给人的印象是错误的——它使值看起来无法更改,而实际上只有字段值不能更改,而不是对象。我认为这里的代码分析过于谨慎——在很多地方,您可能希望将可变类型存储在只读字段中,特别是如果它是私有的,在静态初始值设定项中初始化,然后在代码中从不发生变化

然而,虽然字段受到保护,但派生类滥用它的风险更大。就我个人而言,我喜欢我所有的领域都是私有的。另一方面,我不知道你的代码-可能是你已经权衡了这些可能性,决定这样做是正确的


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

有人能在这个答案中看到前两个答案中没有的有用信息吗?如果没有,我会删除。是的,你的答案很有帮助,请不要删除它。事实上,我经常对我修改的私有字段使用只读(而不是静态)。我要确保的唯一一件事是实例始终是相同的,并且以后不会意外地交换它。所以我认为可变类型的只读仍然有用。它是有效的-你只需要确保每个人都理解只读修饰符的限制。@Jon,你会说私有字段应该被标记为
readonly
,这是理所当然的,除非你知道字段的值需要重新分配吗?换句话说,在将私有字段标记为只读时,如果字段是可变的,您会犹豫吗?