J'essaie d'utiliser le code de cet article: Creating Fake Enums, mais je ne peux pas comprendre pourquoi cela ne fonctionne pas.Fake enum en C#
Ce code:
Console.WriteLine(FakeEnum.One.FriendlyName);
Console.WriteLine(FakeEnum.Four.FriendlyName);
génère une 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
Si je commente les membres déclarés avec le constructeur (int)
, tout le reste fonctionne:
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);
Maintenant, si Je fais les constructeurs public
, le code suivant fonctionne juste f ine:
FakeEnum a = new FakeEnum(14, "1 4");
FakeEnum b = new FakeEnum(28);
Console.WriteLine(a.FriendlyName);
Console.WriteLine(b.FriendlyName);
Je manque juste d'idées - qu'est-ce que je manque, et qu'est-ce qui génère l'exception lors de l'utilisation du code original?
Pouvez-vous me dire pourquoi la déclaration de FakeEnum.Four déclenche l'exception, mais ne déclare pas une nouvelle variable utilisant le même constructeur? – alexandrul
@alexandrul: Parce qu'il regarde les champs de l'énumération * pendant que le type est encore en cours d'initialisation *. Par conséquent, certains de ces champs sont null, ce qui déclenche le problème. Cette classe essaie d'être trop intelligente pour son propre bien, IMO. –
(A ce propos, rendre les constructeurs publics supprime un point important d'une énumération - cela doit être un * ensemble de valeurs fixe *.) –