C# CA2104警告:有没有办法将类标记为“不可变”以抑制它?

C# CA2104警告:有没有办法将类标记为“不可变”以抑制它?,c#,immutability,code-analysis,C#,Immutability,Code Analysis,考虑下面的代码,它会引发 有人知道一种将类标记为不可变的方法,这种方法会抑制警告CA2104吗 我尝试装饰MutableClass,但没有成功的希望(因为该属性对于表单编辑器来说是非常清楚的),而且肯定不起作用 我假设代码分析在确定是否发出CA2104时使用了已知的不可变类型列表,因此我们不能使用相同的方法 我想,即使你可以将一个类标记为不可变的,编译器也无法真正检查它是否为真,但至少它可以成为一个有用的指示器 不管怎么说,我有没有忽略了什么特性?如果没有,就必须镇压 目前似乎没有其他办法可以做

考虑下面的代码,它会引发

有人知道一种将类标记为不可变的方法,这种方法会抑制警告CA2104吗

我尝试装饰
MutableClass
,但没有成功的希望(因为该属性对于表单编辑器来说是非常清楚的),而且肯定不起作用

我假设代码分析在确定是否发出CA2104时使用了已知的不可变类型列表,因此我们不能使用相同的方法

我想,即使你可以将一个类标记为不可变的,编译器也无法真正检查它是否为真,但至少它可以成为一个有用的指示器

不管怎么说,我有没有忽略了什么特性?如果没有,就必须镇压

目前似乎没有其他办法可以做到这一点

我确实找到了

他以“想象我们有一个不可变的属性”开始


这很有趣——他费劲地编写了一些新的FxCop规则,对属性为不可变的类型进行了一些分析。

一个
受保护的只读字段实际上并不清楚。作为受保护的
,您可能希望派生类可以初始化字段:

public class Test
{
    protected readonly ImmutableClass ImmutableMember;
}

public class SpecialTest : Test
{
    public SpecialTest() { ImmutableMember = new ImmutableClass; }
}
但是,事实并非如此——您将得到一个编译错误(CS0191)

我不知道CA2104背后的确切动力,但您可以通过以下途径获得相同的结果,而无需readonly:

public class Test
{
    protected ImmutableClass ImmutableMember {get; private set;}

    public Test()
        :this(new ImmutableClasse())
    {
    }

    public Test(ImmutableClass immutableClass)
    {
        ImmutableMember = new ImmutableClasse();
    }
}
避免使用CA2104

更新: w、 对于注释(以及未来的读者),正如您所说,您可以使用一个backing字段来获取只读,并提供一个受保护的getter来在派生类中获取它:

public class Test
{
    private readonly ImmutableClass immutableMember;

    protected ImmutableClass ImmutableMember { get { return immutableMember; } }

    public Test(ImmutableClass immutableMember)
    {
        this.immutableMember = immutableMember;
    }
}

为什么要将其标记为
只读
?@Davin Tryon:因为属性必须在构造中初始化,并且此后不会更改,就像总是使用
只读
。当然和你把任何东西标为只读的原因是一样的?我想是的,你只是没有提到。在我看来,这是一次性的压制。是的,看起来是。我并没有过分担心,我只是希望有一个适当的属性来表达我的意图。“Pure”函数(用于代码契约)有一个
[Pure]
属性;你可能认为微软会为
不可变
引入一些东西。也许我应该去建议一下……你有没有尝试过
protectedImmutableClass ImmutableMember{get;private set;}
然后只允许通过一个基构造函数初始化
ImmutableMember
?谢谢-我认为这样做的方式有些类似。事实上,我将使
只读
字段私有,并通过受保护的属性将其公开给派生类。我会将此标记为答案,并将最终使用的代码添加到原始问题中。
public class Test
{
    private readonly ImmutableClass immutableMember;

    protected ImmutableClass ImmutableMember { get { return immutableMember; } }

    public Test(ImmutableClass immutableMember)
    {
        this.immutableMember = immutableMember;
    }
}