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

时间:2013-04-01 08:21:10

标签: c# immutability code-analysis

请考虑以下代码,这会引发CA2104: Do not declare read only mutable reference types.

public class Test
{
    // This provokes CA2104: "Do not declare read only mutable reference types".
    protected readonly ImmutableClass ImmutableMember;
}

public class ImmutableClass
{
}

是否有人知道如何以抑制警告CA2104的方式将类标记为不可变?

我尝试用[ImmutableObject(true)]装饰MutableClass而没有成功的希望(因为表格编辑器使用该属性非常清楚),而且确实无法使用。

我认为Code Analysis在确定是否发出CA2104时使用已知的不可变类型列表,因此我们不能使用相同的方法。

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

无论如何,我有什么属性可以忽略吗?如果没有,则必须进行抑制。

目前似乎没有替代方法

我确实找到了an interesting blog from Joe Duffy (author of "Concurrent Programming On Windows") about this kind of thing

他从开始“想象一下,我们有一个ImmutableAttribute。” ... :)

这很有意思 - 他不得不编写一些新的FxCop规则,对属于不可变的类型进行一些分析。

1 个答案:

答案 0 :(得分:5)

protected readonly字段并不是那么清楚。作为protected,您可能希望派生类可以初始化字段:

public class Test
{
    protected readonly ImmutableClass ImmutableMember;
}

public class SpecialTest : Test
{
    public SpecialTest() { ImmutableMember = new ImmutableClass; }
}

但是,情况并非如此 - 您将收到编译错误(CS0191)。

我不知道CA2104背后的确切动力,但是你可以通过以下方式获得相同的结果:

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

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

    public Test(ImmutableClass immutableClass)
    {
        ImmutableMember = new ImmutableClasse();
    }
}

并避开CA2104。

更新

w.r.t。对于评论(以及未来的读者),正如您所说,您可以使用支持字段来获取只读并提供受保护的getter以在派生类中获取它:

public class Test
{
    private readonly ImmutableClass immutableMember;

    protected ImmutableClass ImmutableMember { get { return immutableMember; } }

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