我有以下类:
public class AssignmentStatusCode
{
public static AssignmentStatusCode Pending { get; } = new AssignmentStatusCode("P");
public static AssignmentStatusCode Rejected { get; } = new AssignmentStatusCode("R");
public static AssignmentStatusCode Approved { get; } = new AssignmentStatusCode("A");
public static implicit operator string(AssignmentStatusCode assignmentStatusCode)
{
return assignmentStatusCode.Value;
}
private static readonly HashSet<string> ValidStatusCodes = new HashSet<string>(new[] { "A", "R", "P" });
public AssignmentStatusCode(string value)
{
if (!ValidStatusCodes.Contains(value))
{
throw new ArgumentOutOfRangeException(nameof(value),
$"Value must be {string.Join(", ", ValidStatusCodes.Select(c => $"'{c}'"))}.");
}
Value = value;
}
public string Value { get; }
}
当我使用
var a = new AssignmentStatusCode("A")
创建此类的实例时,实例构造函数中if
检查语句处抛出NullReferenceException
异常。调试表明ValidStatusCodes
为null
。
ValidStatusCodes
具有静态初始化器。
根据C#规范:
如果类中存在静态构造函数(§10.12),则在执行该静态构造函数之前即刻执行静态字段初始化器。否则,在第一次使用该类的静态字段之前,将在实现依赖时间内执行静态字段初始化器。
为什么我的静态字段在构造函数中被访问之前未被初始化?我感觉自己错过了非常简单的东西,但我已经花了太多时间进行调试,没有任何进展;现在是请求帮助的时候了。
显然,如果我更加仔细地阅读了规范,我就会注意到我引用的段落的开头,这是我问题的根源。
10.5.5.1 静态字段初始化 类的静态字段变量初始化器对应于按照类声明中它们出现的文本顺序执行的一系列赋值。如果类中存在静态构造函数(§10.12),则在执行该静态构造函数之前即刻执行静态字段初始化器。否则,在第一次使用该类的静态字段之前,将在实现依赖时间内执行静态字段初始化器。
感谢大家的帮助。
private static readonly HashSet<string> ValidStatusCodes ...
移动到public static AssignmentStatusCode Pending ...
之前,应该就可以工作了。 - Alessandro D'Andria