静态或公共构造函数上的数据初始化

时间:2014-03-26 14:03:25

标签: c#

我想知道在静态构造函数而不是公共构造函数上初始化数据是否存在缺陷。我假设前两个代码狙击手做同样的事情。

下面的简短例子

    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()}
            };
    }         

    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());
            }
    }

或使用公共构造函数

    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());
            }
    }

编辑:

在最后一个修剪器中更改了已删除的静态,因此在创建新的测试时刻时不会抛出任何异常

2 个答案:

答案 0 :(得分:1)

使用公共构造函数的主要问题是每次创建类Test的对象时都会执行普通的公共构造函数。每次创建languages实例时,这都会导致静态Test字典增长。但是,在此示例中,Test的第二个实例将抛出ArgumentException,因为字典要求所有键都是唯一的。

对于使用静态构造函数初始化的选项或者声明静态成员的选项,编译后的代码非常相似,因为第一次声明类型为Test的变量时,此代码将运行并填写你的字典。

请记住,静态构造函数将在初始化所有静态成员后运行。

修改

更新了问题,使字典在最后一个示例中成为实例成员。

现在这些例子之间的主要区别在于记忆和适应性的使用。如果存在作为Test的每个实例的成员的字典实例,则大量实例将使用更多内存。这可能是这里所需要的,特别是如果Test的实例可能需要调整字典的内容,但不影响其他实例。如果字典在Test的所有实例中始终包含相同的元素,那么将字典设置为静态是有意义的 - 并且让所有实例在内存中共享相同的字典。

答案 1 :(得分:0)

我认为首先你要了解每个人的特征。

From MSDN:

静态构造函数具有以下属性:

  • 静态构造函数不接受访问修饰符或具有参数。
  • 在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数来初始化类。
  • 无法直接调用静态构造函数。 用户无法控制程序中何时执行静态构造函数。
  • 静态构造函数的典型用法是当类使用日志文件并使用构造函数将条目写入此文件时。
  • 当构造函数可以调用LoadLibrary方法时,静态构造函数在为非托管代码创建包装类时也很有用。

因此,只要考虑上述情况,就可以问自己很多问题,例如:

  • 初始化此构造函数是否很昂贵?如果是这样,也许我需要控制它何时被初始化,我将无法使用静态构造函数。
  • 我是否需要通过多个线程访问此对象?如果是这样,我可以使用普通的公共构造函数来解决问题。对于非托管代码也是如此。