在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)但更糟糕的是,即使我这样做,那么后来有人可能会意外地引入可变性,但是其他人仍然会有一种虚假的安全感,因为有人手动将抑制措施放在那里说“我检查过这是不可变的“?
答案 0 :(得分:5)
你是对的 - 在这种情况下这是误报。您唯一的选择是单独抑制或关闭警告,并且缺点与您为每个选项描述的完全相同。
避免此警告的其他选项包括:
不要使用静态字段。相反,您可以使用带有公共get和private集的静态属性,并在构造函数中初始化而不是内联。
创建这些不可变值类型,它们将绕过警告,但在某些情况下可能会提供不同的行为。在您的情况下,这可能是也可能不是一种选择。