简体   繁体   中英

Data initialization over static or public constructor

I'd like to know if there is a drawback initializing data over a static constructor instead of a public constructor. I assume that the first two code snipers do the same.

a short example below

    class Test
    {
        private readonly static Dictionary<string, string> languages = 
            new Dictionary<string,string>()
            {
                {"de-CH", "Language.German".Translate()},
                {"fr-CH", "Language.French".Translate()},
                {"it-CH", "Language.Italian".Translate()}
            };
    }         

or

    class Test
    {
            private readonly static Dictionary<string, string> languages = 
            new Dictionary<string,string>();

            static LanguageChangeFragment()
            {
                languages.Add("de-CH", "Language.German".Translate());
                languages.Add("fr-CH", "Language.French".Translate());
                languages.Add("it-CH", "Language.Italian".Translate());
            }
    }

or using a public constructor

    class Test
    {
            private readonly Dictionary<string, string> languages = 
                    new Dictionary<string,string>();

            public LanguageChangeFragment()
            {
                languages.Add("de-CH", "Language.German".Translate());
                languages.Add("fr-CH", "Language.French".Translate());
                languages.Add("it-CH", "Language.Italian".Translate());
            }
    }

Edit:

Changed removed static in last snipper, so that no exception is thrown when creating a new Test instant

The main problem with using the public constructor is that the normal public constructor is executed every time an object of class Test is created. This would cause the static languages dictionary to grow each time you created an instance of Test . In this example however, the second instance of Test would throw an ArgumentException because a dictionary requires that all keys are unique.

As for the options you show for initialization using a static constructor or where you declare the static member, the compiled code is very similar, since the first time a variable of type Test is declared, this code will run and populate your dictionary.

Keep in mind that the static constructor will run after all static members are initialized.

EDIT

The question was updated to make the dictionary an instance member in the last example.

The main difference between these examples now is in the use of memory and adaptability. If there is a dictionary instance that is a member of each instance of Test , a large number of instances will use more memory. That may be what is required here, especially if an instance of Test might need to adapt the contents of the dictionary, but not affect other instances. If the dictionary will always contain the same elements in all instances of Test , then it would make sense to make the dictionary static - and let all instances share the same dictionary in memory.

I think first you have to understand the characteristics of each.

From MSDN:

Static constructors have the following properties:

  • A static constructor does not take access modifiers or have parameters.
  • A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
  • A static constructor cannot be called directly. The user has no control on when the static constructor is executed in the program.
  • A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file.
  • Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.

So just by thinking about the above, ask yourself many questions, for instance:

  • Is it expensive to initialize this constructor? If so, maybe I need to control when it is initialized, which I will not be able to do with a static constructor.
  • Do I need to access this object via multiple threads? If so, I can get myself into trouble using the normal public constructor. Same for unmanaged code.

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