简体   繁体   中英

The type initializer for '' threw an exception

Consider this code:

public class CountEnum : EnumDataType
    {
        public static readonly CountEnum CANADA = new CountEnum("CA", "Canada");
        public static readonly CountEnum DEFAULT = new CountEnum();
        private static readonly EnumDataTypeList OPTIONS = new EnumDataTypeList();
        public static readonly CountEnum UNITED_STATES = new CountEnum("US", "United States");
        public static readonly CountEnum UNSET = new CountEnum();


        private CountEnum()
        {
        }

        private CountEnum(string code, string name)
        {
            base.code = code;
            base.name = name;
            OPTIONS.Add(this); // This is the line 23
        }

Below are the exception details:

System.TypeInitializationException was caught
  Message=The type initializer for 'CP.BusinessLogic.VConfig' threw an exception.
  Source=CP.BusinessLogic
  TypeName=CP.BusinessLogic.VConfig
  StackTrace:
       at CP.BusinessLogic.VConfig.get_Instance()
       at CP.Fac.CPFac.GetActs() in C:\tfs_src\TeamProject\Main\Source\DApp\CPApp\Fac\CPFac.cs:line 170
  InnerException: System.TypeInitializationException
       Message=The type initializer for 'CP.Types.CountEnum' threw an exception.
       Source=CP.BusinessLogic
       TypeName=CP.Types.CountEnum
       StackTrace:
            at CP.BusinessLogic.VConfig..ctor() in C:\tfs_src\TeamProject\Main\Source\DApp\CPApp\BusinessLogic\VConfig.cs:line 14
            at CP.BusinessLogic.VConfig..cctor() in C:\tfs_src\TeamProject\Main\Source\DApp\CPApp\BusinessLogic\VConfig.cs:line 11
       InnerException: System.NullReferenceException
            Message=Object reference not set to an instance of an object.
            Source=CP.DataObject
            StackTrace:
                 at CP.Types.CountEnum..ctor(String code, String name) in C:\tfs_src\TeamProject\Main\Source\DApp\CPApp\Types\CountEnum.cs:line 23
                 at CP.Types.CountEnum..cctor() in C:\tfs_src\TeamProject\Main\Source\DApp\CPApp\Types\CountEnum.cs:line 8
            InnerException:

I am unable to figure out why I am getting this exception at runtime. I am not getting any build errors and the code looks correct.

Judging by your stack trace, I think you've missed out the guilty code. For example, maybe it actually looks like this:

public class CountEnum
{
   public static readonly CountEnum DEFAULT = new CountEnum();
   private static readonly List<CountEnum> AllInstances = new List<CountEnum>();

   private CountEnum()
   {
       AllInstances.Add(this);
   }
}

That would behave the way the stack trace shows, with the CountEnum constructor throwing a NullReferenceException . However, we can't tell for sure as you haven't included the body of the CountEnum constructor (or indeed posted valid code for CountEnum at all).

Fundamentally though, this is the bit of the stack trace you should be looking at:

InnerException: System.NullReferenceException
     Message=Object reference not set to an instance of an object.
     Source=CP.DataObject
     StackTrace:
          at CP.Types.CountEnum..ctor(String code, String name) in C:\...\CountEnum.cs:line 23
          at CP.Types.CountEnum..cctor() in C:\...\CountEnum.cs:line 8

You should be looking at line 23 of CountEnum.cs - that's what's throwing the exception.

EDIT: Okay, now we can see the code in question, it's very similar to my guess. Look at this code:

public static readonly CountEnum CANADA = new CountEnum("CA", "Canada");
public static readonly CountEnum DEFAULT = new CountEnum();
private static readonly EnumDataTypeList OPTIONS = new EnumDataTypeList();

These variables will be initialized in the order you've specified - so the call to CountEnum("CA", "Canada") will execute before OPTIONS has a non-null value... and when you try to add it to OPTIONS , you'll get an exception in a perfectly normal way.

You can fix this just by moving the declaration of OPTIONS to the top:

private static readonly EnumDataTypeList OPTIONS = new EnumDataTypeList();
public static readonly CountEnum CANADA = new CountEnum("CA", "Canada");
public static readonly CountEnum DEFAULT = new CountEnum();

That's guaranteed to work, but it's a fairly brittle design. I have used designs like this in the past, but you can get into fiddly messes when you require a particular initialization order.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM