我有这样的课程
class MyClass{
const int Item1 = 1;
const int Item2 = 2;
const int Item3 = 3;
...
}
class MySecondClass : MyClass
{
const int Item1 = 4;
const int Item2 = 5;
const int Item3 = 6;
...
}
是否有自动设置这些值的方法,确保它们是连续的并且仍然是常量?我们在合并时出现问题,其中两个开发人员添加了一个项目,最后我们得到两个具有相同值的项目。
目前我们检查单元测试是否会发生这种情况,并在测试中断时进行修复。但是在编译期间我们可以做更好的事情会更好:
int i=0;
class MyClass{
const int Item1 = i;
const int Item2 = ++i;
const int Item3 = ++i;
...
}
class MySecondClass : MyClass{
const int Item4 = ++i;
const int Item5 = ++i;
const int Item6 = ++i;
...
}
编辑: 这是几十个类中的遗留代码,我无法将结构更改为枚举。
答案 0 :(得分:3)
class A
{
static A() { }
protected static int i = 0;
public static readonly int Item1 = i++;
public static readonly int Item2 = i++;
public static readonly int Item3 = i++;
}
class B : A
{
static B() { }
public static readonly int Item4 = i++;
public static readonly int Item5 = i++;
public static readonly int Item6 = i++;
}
您无法使用const
,因为i++
不被视为常量表达式,但static readonly
是类似的约束。
根据10.4.5.1,有必要明确地包含静态构造函数来继承静态构造函数的初始化顺序规则。
根据10.11:
如果一个类包含任何带有初始化器的静态字段,那么这些字段 初始化程序在紧接之前以文本顺序执行 执行静态构造函数。
和
类的静态构造函数在给定的时间内最多执行一次 应用领域。触发静态构造函数的执行 在应用程序中发生以下第一个事件 域:
- 创建了一个类的实例。
- 引用该类的任何静态成员。
因为B
引用了i
的静态成员A
,所以A
的静态构造函数必须先执行。因此,您应该得到保证(如果我已经正确地解释了这一点)Item1 == 0, …, Item6 == 5
,只要没有A
的其他后代也会改变i
。< / p>
如果您将另一个后代C
添加到A
,那么如果您希望之前订购B
,则需要从C
引用B
的静态字段C
(反之亦然)。
枚举怎么样?
enum Items : int
{
Item1 = 1,
Item2,
Item3,
// …
}
你可以退出:
var x = (int)Items.Item1;
答案 1 :(得分:2)
如果你有一个包含所有常量的类,并且该类不包含任何其他内容,则枚举是合适的(请参阅erisco的回答)。
对于更复杂的情况,例如您在编辑问题中描述的情况,您最好的选择可能是代码生成。您可以创建类partial,并从T4 template生成类的一部分,这允许您为生成的代码实现任何您喜欢的逻辑。