【问题标题】:Initialize static field in constructor. It's normal?在构造函数中初始化静态字段。这是正常的?
【发布时间】:2011-07-02 00:19:52
【问题描述】:
public class SharedCacheData : ISharedCacheData
{
    private readonly ISharedPetsService mPetsService;
    private static ISharedEmployeeService mSharedEmployeeService;
 public SharedCacheData(ISharedPetsService petsService, ISharedEmployeeService employeeService)
    {
        mPetsService = petsService;
        mSharedEmployeeService = employeeService;
    }

    public static string GetUserFullName(string key)
    {
        Hashtable value = HttpContext.Current.Application[USERFULLNAME_KEY] as Hashtable;
        if (value == null)
        {
            value = new Hashtable();
            HttpContext.Current.Application[USERFULLNAME_KEY] = value;
        }
        if (value.ContainsKey(key))
            return value[key] as string;

        string name = mSharedEmployeeService.FindOneUser(key);
        value[key] = name;
        return name;
    }

是否在构造函数中初始化静态字段mSharedEmployeeService(服务)?

【问题讨论】:

    标签: c# static constructor


    【解决方案1】:

    好的做法是“静态”字段应该内联初始化希望这是有道理的。 下面的代码 sn-ps 相同

     namespace staticFieldsInit
    {
      public class Foo
      {
        static int  Id;
        static string Name;
    
        static Foo() // Noncompliant
        {
          Id = 10;
          ResourceManager sm =  new ResourceManager("strings", Assembly.GetExecutingAssembly());
          s = sm.GetString("mystring");
        }
      }
    }
    
    

    上面代码的更好写法

    
    namespace staticFieldsInit
    {
      public class Foo
      {
        static int Id =10;
        static string Name = InitString();
    
        static string InitString()
        {
          ResourceManager sm = new ResourceManager("strings", Assembly.GetExecutingAssembly());
          return sm.GetString("mystring");
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      静态字段是类成员;构造函数用于创建实例成员。 并且在实例 ctors 中初始化静态字段与 OOPS 哲学背道而驰。你当然可以这样做;但这会改变为该类型创建的每个实例的静态字段的值。

      要初始化静态字段,请使用静态初始化器 - 在类加载时调用,即在创建任何实例成员之前 - 在 ant ctor 调用之前。

      “静态构造函数”实际上并不构造实例。我更喜欢称它为静态初始化程序。

      静态初始化器也不允许访问修饰符。

      【讨论】:

      • 静态初始化器和静态构造器有些不同。静态构造函数是规范中的名称,因此即使您不喜欢它,我也鼓励您使用它。静态初始化器不是我知道的规范术语,但可以很容易地用于静态 field 初始化器......但是一个具有静态构造函数的类和一个仅具有静态字段初始化器的类有不同的时间。
      【解决方案3】:

      不建议这样做,而且通常是不好的做法:如果事先没有创建 SharedCacheData 的实例,现在调用静态方法 GetUserFullName() 将导致异常。

      【讨论】:

        【解决方案4】:

        在静态构造函数中初始化它会更有意义:

        http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx

        class SimpleClass
        {
            // Static constructor
            static SimpleClass()
            {
                //...
            }
        }
        

        【讨论】:

          【解决方案5】:

          不,这通常是个坏主意。每次创建新实例时,它都会替换静态变量。这几乎肯定不是你想要做的。

          我想知道实际上这里是否应该有两个类——一个用于宠物服务,一个用于员工服务。从提供的代码中很难看出,但我们在这里得到的东西看起来确实不是一个好主意。

          【讨论】:

          • 对于将来阅读本文的人:我要补充一点,使用静态构造函数(如 Mark Robinson 所述)将是可行的方法。
          • @BKSpureon:不一定。没有实际的静态构造函数,静态字段初始化器可能就足够了。这取决于需要什么时间。
          猜你喜欢
          • 2011-02-15
          • 2011-07-02
          • 1970-01-01
          • 2012-01-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-25
          相关资源
          最近更新 更多