7

在 C# 中,我想制作“智能”枚举,这在 Java 中是可能的,其中附加到枚举值的信息不仅仅是底层 int。我偶然发现了一个创建类(而不是枚举)的方案,如下面的简单示例所示:

public sealed class C
{
    public static readonly C C1 = new C(0, 1);
    public static readonly C C2 = new C(2, 3);

    private readonly int x;
    private readonly int y;

    private C(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public int X
    {
        get
        {
            return this.x;
        }
    }

    public int Y
    {
        get
        {
            return this.y;
        }
    }
}

但是当我在上面运行 Visual Studio 的“代码分析器”时,它给了我警告 C2104,“不要声明只读可变引用类型”。

我明白为什么您通常不想声明只读可变引用类型,但是......我的类不是可变的,是吗?

阅读警告的文档,似乎他们只是假设任何只读引用类型都是可变的。例如,它说如果类型真的是不可变的,那么可以随意取消这个警告。事实上,对于下面更简单的类,它给了我同样的警告:

public sealed class C
{
    public static readonly C C1 = new C();
    public static readonly C C2 = new C();

    private C()
    {
    }
}

所以,好吧,除非我严重误解了可变性,否则 CA2104 不理解它。它的建议是让我抑制出现的每一行的警告,只要我确定该类确实是不可变的。但:

(1) 因此,除非我完全关闭此检查,否则每次我使用不可变只读成员时都必须抑制它,对于任何给定的枚举,我可能会执行数百次?

(2) 但更糟糕的是,即使我这样做了,那么稍后有人可能会意外引入可变性,但其他人仍然会有错误的安全感,因为有人手动将抑制放在那里说“我检查过,这是不可变的“?

4

1 回答 1

5

你是对的 - 在这种情况下这是一个误报。您唯一的选择是单独抑制或关闭警告,缺点与您对每个选项的描述完全相同。

避免此警告的其他选项包括:

  • 不要使用静态字段。相反,您可以使用带有公共 get 和私有集的静态属性,并在构造函数中初始化而不是内联。

  • 制作这些不可变的值类型,这将绕过警告,但在某些情况下可能会给出不同的行为。在您的情况下,这可能是也可能不是一个选项。

于 2013-05-04T21:44:49.360 回答