今天,我发现在C#中进行某种枚举可能很有趣,类似于Java中的类枚举(已经多次完成)但是作为不可变的结构。我想出了类似的东西:
public struct TestStruct {
public static readonly TestStruct Value1 = 1;
public static readonly TestStruct Value2 = 2;
public static readonly TestStruct Value3 = 3;
private int _value;
private TestStruct(int value) {
_value = value;
}
public static implicit operator int(TestStruct instance) {
return instance._value;
}
}
代码编译正确,但是当我尝试访问TestStruct.Value2
时,会发生NullReferenceException
。
这只是一个测试,但现在我想知道...... 静态只读 TestStructs
会发生什么?为什么我可以为它们分配一个整数,虽然它们没有被初始化?
更新
这个编译。
public struct LogLevel
{
// log levels
public static readonly LogLevel Information = 0x0000;
public static readonly LogLevel Warning = 0x0001;
public static readonly LogLevel Error = 0x0002;
public static readonly LogLevel Verbose = 0x0004;
public static readonly LogLevel Debug = 0x0008;
public static readonly LogLevel Trace = 0x0016;
public static readonly LogLevel Critical = 0x0032;
public static readonly LogLevel Fatal = 0x0064;
private static readonly Dictionary<int, LogLevel> Levels
= new Dictionary<int, LogLevel>();
private readonly int _value;
private LogLevel(int value)
{
if (Levels.ContainsKey(value))
throw new ArgumentException("Level already defined.");
_value = value;
Levels.Add(value, this);
}
public static implicit operator LogLevel(int value)
{
LogLevel level;
if (!Levels.TryGetValue(value, out level))
throw new ArgumentOutOfRangeException("value");
return level;
}
public static implicit operator int(LogLevel level)
{
return level._value;
}
}
更新2
// extension method for log levels
public static void Debug(this ILogger logger, string message)
{
logger.Write(message, LogLevel.Debug);
}
// method on ILogger, implementation is Log4NetLogger (wrapper)
void Write(string message, LogLevel severity);
// call (simple)
Logger.Debug("Test");
答案 0 :(得分:2)
这里有两个问题:
当您初始化字段时,您正在使用int
的隐式转化...期望该值已经 。您应该使用构造函数。所以这个:
public static readonly LogLevel Information = 0x0000;
应该是
public static readonly LogLevel Information = new LogLevel(0x0000);
您在Levels
变量初始化之前尝试访问字典。您需要移动此声明:
private static readonly Dictionary<int, LogLevel> Levels
= new Dictionary<int, LogLevel>();
...在字段声明之上。这样它在字段初始化程序调用构造函数之前就已初始化。
此时,它应该有效。它不一定是我自己使用的设计,但它至少可以消除你目前所遇到的问题。