C# 中的假枚举
我正在尝试使用本文中的代码:创建假枚举,但我不明白为什么它不起作用。
此代码:
Console.WriteLine(FakeEnum.One.FriendlyName);
Console.WriteLine(FakeEnum.Four.FriendlyName);
生成异常:
System.TypeInitializationException was unhandled
Message="The type initializer for 'FakeEnum' threw an exception."
Source="FakeEnum1"
TypeName="FakeEnum"
StackTrace:
at FakeEnum1.Program.Main(String[] args) in ..\Test\FakeEnum1\Program.cs:line 26
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.NullReferenceException
Message="Object reference not set to an instance of an object."
Source="FakeEnum1"
StackTrace:
at FakeEnum.op_Equality(FakeEnum a, FakeEnum b) in ..\Test\FakeEnum1\FakeEnum.cs:line 158
at FakeEnum.ToString(String format) in ..\Test\FakeEnum1\FakeEnum.cs:line 31
at FakeEnum.ToString() in ..\Test\FakeEnum1\FakeEnum.cs:line 25
at FakeEnum..ctor(Int32 value, String friendlyName) in ..\Test\FakeEnum1\FakeEnum.cs:line 171
at FakeEnum..ctor(Int32 value) in ..\Test\FakeEnum1\FakeEnum.cs:line 165
at FakeEnum..cctor() in ..\Test\FakeEnum1\FakeEnum.cs:line 13
如果我注释使用 (int)
构造函数声明的成员,则其他一切都有效:
public static readonly FakeEnum One = new FakeEnum(1, "One's Friendly Name");
public static readonly FakeEnum Two = new FakeEnum(2, "Two's Friendly Name");
public static readonly FakeEnum Three = new FakeEnum(3, "Three's Friendly Name");
//public static readonly FakeEnum Four = new FakeEnum(4);
//public static readonly FakeEnum Five = new FakeEnum(5);
//public static readonly FakeEnum Six = new FakeEnum(6);
现在,如果我将构造函数设置为 public
,则以下代码工作得很好:
FakeEnum a = new FakeEnum(14, "1 4");
FakeEnum b = new FakeEnum(28);
Console.WriteLine(a.FriendlyName);
Console.WriteLine(b.FriendlyName);
我只是没有想法了 - 我错过了什么,以及在使用原始代码时产生异常的原因是什么?
I'm trying to use the code from this article: Creating Fake Enums, but I can't figure out why it doesn't work.
This code:
Console.WriteLine(FakeEnum.One.FriendlyName);
Console.WriteLine(FakeEnum.Four.FriendlyName);
generates an exception:
System.TypeInitializationException was unhandled
Message="The type initializer for 'FakeEnum' threw an exception."
Source="FakeEnum1"
TypeName="FakeEnum"
StackTrace:
at FakeEnum1.Program.Main(String[] args) in ..\Test\FakeEnum1\Program.cs:line 26
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.NullReferenceException
Message="Object reference not set to an instance of an object."
Source="FakeEnum1"
StackTrace:
at FakeEnum.op_Equality(FakeEnum a, FakeEnum b) in ..\Test\FakeEnum1\FakeEnum.cs:line 158
at FakeEnum.ToString(String format) in ..\Test\FakeEnum1\FakeEnum.cs:line 31
at FakeEnum.ToString() in ..\Test\FakeEnum1\FakeEnum.cs:line 25
at FakeEnum..ctor(Int32 value, String friendlyName) in ..\Test\FakeEnum1\FakeEnum.cs:line 171
at FakeEnum..ctor(Int32 value) in ..\Test\FakeEnum1\FakeEnum.cs:line 165
at FakeEnum..cctor() in ..\Test\FakeEnum1\FakeEnum.cs:line 13
If I comment the members declared with the (int)
constructor, everything else works:
public static readonly FakeEnum One = new FakeEnum(1, "One's Friendly Name");
public static readonly FakeEnum Two = new FakeEnum(2, "Two's Friendly Name");
public static readonly FakeEnum Three = new FakeEnum(3, "Three's Friendly Name");
//public static readonly FakeEnum Four = new FakeEnum(4);
//public static readonly FakeEnum Five = new FakeEnum(5);
//public static readonly FakeEnum Six = new FakeEnum(6);
Now, if I make the constructors public
, the following code works just fine:
FakeEnum a = new FakeEnum(14, "1 4");
FakeEnum b = new FakeEnum(28);
Console.WriteLine(a.FriendlyName);
Console.WriteLine(b.FriendlyName);
I just run out of ideas - what am I missing, and what generates the exception when using the original code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
就是这样:
“==”正在调用 == 运算符,它不希望左侧为空:
您可以像这样修复运算符:(
或者使用
object.Equals
,正如另一个答案中所指出的 - 哦!)或者您可以更改它以使
Equals
委托给 == 而不是相反。我个人认为这门课看起来有点毛茸茸的。我什至不清楚为什么 == 和 != 需要重载,或者为什么 Equals 需要重写,除非你确实有两个具有相同值的单独对象(例如,由于序列化,这将是令人讨厌的)反正)。
It's this bit:
That "==" is calling the == operator, which doesn't expect the left hand side to be null:
You can fix the operator like this:
(Or by using
object.Equals
, as pointed out in another answer - doh!)or you could change it to make
Equals
delegate to == instead of the other way round.Personally I'd say this class is looking a tad hairy. It's not even clear to me why == and != need overloading or indeed why Equals needs overriding unless you really have two separate objects with the same value (e.g. due to serialization, which is going to be icky anyway).
我自己还没有真正尝试过,但是 == 和 != 操作肯定没有正确实现。应该是:
I haven't really tried it myself, but the == and != operations are definitely not implemented correctly. Should be:
object.equals 调用对象的 == 运算符(这将调用 object.equals 方法,该方法将调用对象(这将调用 ... )),剩下的就是堆栈溢出。
它调用对象的 equals 方法来测试底层整数值,以模拟枚举实例的行为方式。
object.equals calls the object's == operator (which would call the object.equals method which would call the objects (which would call ... ) ) and all you'd be left with is a stack overflow.
it calls the object's equals method to test the underlying integer value to simulate how an enum instance would behave.