12

考虑下面的代码,它引发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 的方式将类标记为不可变的方法?

MutableClass我尝试了装饰[ImmutableObject(true)]但没有成功的希望(因为该属性非常清楚地供表单编辑器使用),果然它不起作用。

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

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

无论如何,有什么我忽略的属性吗?如果没有,压制将不得不做。

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

我确实从 Joe Duffy(“Windows 上的并发编程”的作者)那里找到了一篇关于这种事情的有趣博客

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

这很有趣——他不厌其烦地编写了一些新的 FxCop 规则来对归因于不可变的类型进行一些分析。

4

1 回答 1

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。

更新:

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

public class Test
{
    private readonly ImmutableClass immutableMember;

    protected ImmutableClass ImmutableMember { get { return immutableMember; } }

    public Test(ImmutableClass immutableMember)
    {
        this.immutableMember = immutableMember;
    }
}
于 2013-04-01T15:02:47.937 回答