【问题标题】:Help with static constructor in c#帮助 c# 中的静态构造函数
【发布时间】:2010-10-07 17:01:05
【问题描述】:

我需要帮助在 c# 中初始化静态只读变量。我有一堂有这个签名的课

public class AgentDescriptions
{
   public static readonly int P1;
   public static readonly int P2;

   static AgentDescriptions()
   {
      int agencyID = 1; //I need to pass this in the constructor somehow
      P1 = GetIDFromDB(agencyID);
      P2 = GetIdFromDB(agencyID);
   }
}

P1 和 P2 在应用程序中反复使用,并且 我试图避免两件事。 1)魔术数字和 2)每次我需要使用 P1 和 P2 时都去数据库。

在应用程序中,我在很多地方都以这种方式使用它们

if (something == AgentDescriptions.P1)
   //Blah();

请帮忙。如何在静态构造函数中传递代理 ID?如果我添加另一个构造函数并在那里传递代理ID,我每次使用它时都必须初始化该类吗?这意味着每次都要去数据库吗?

【问题讨论】:

标签: c# .net


【解决方案1】:

为什么类是静态的。如果你将一个变量传递给构造函数,那么你是在暗示一个具有状态的对象的实例,而不是一个类。

我会将变量设为私有成员变量,只有 get 方法可供它们使用。然后你有一个构造函数,它接受机构 ID 并设置这两个变量。如果您需要维护此类型的单个实例,请使用单例(类中的静态函数,用于存储对象的单个实例或创建新对象(如果尚不存在))。另一方面,如果您需要具有不同机构 ID 的多个对象,那么您已经有了一种机制来执行此操作。

【讨论】:

  • +1 用于建议单身人士。另外,我为破坏你完美的 1000 次代表而道歉。 ://
  • 呃,单身人士。仍然+1。只是不喜欢单身人士。
  • @George Stocker 我要提到单例是有争议的,但我认为它们仍然比原始形式更好。它们将与当前设计相当顺利地插入,同时允许以后更容易地更换为替代品。
  • 差点打到 -1,singlton 不是解决方案,尤其是在存在强烈的不理解状态的情况下
  • 这实际上可能是单例的情况,因为如果我要使用单例,他会遵循我会遵循的规则(状态在对象的整个生命周期中保持不变,并且 您实例化第一个实例时与状态无关)也就是说,鉴于正在传递的机构ID,我认为可能还有其他一些问题......
【解决方案2】:

我会这样做:

public static class AgentDescriptions
{
  public static int P1 { get; private set; }
  public static int P2 { get; private set; }

  public static void Initialize(int AgencyId)
  {
      P1 = GetIDFromDB(AgencyId);
      P2 = GetIDFromDB(AgencyId);
  }
}

如果您想锁定它以便 Initialize 只能被调用一次,那么您可以轻松地使用一个在 Initialize 被调用后引发异常(或其他)的标志。

【讨论】:

    【解决方案3】:

    听起来您确实想要某种缓存。

    public class AgentDescriptions
    {
        static Dictionary<int,int> agentCache = new ...;
        public static int GetP1(int agentID)
        {
           if (!agentCache.ContainsKey(agentID))
              agentCache.Add(agentID, GetIdFromDB(agencyID));
    
           return agentCache[agentID];
        }
    
        ...
    

    【讨论】:

      【解决方案4】:

      这里的其他问题中也有类似的单例问题。

      class AgentDescriptions 
      {
          AgentDescriptions()
          {
              P1 = GetIDFromDB(agencyID);
              P2 = GetIdFromDB(agencyID);
          }
          static public AgentDescriptions Instance 
          {
              get 
              {
                  if (_instance==null)
                  {
                      _instance=new AgentDescriptions();
                  }
                  return _instance;
              }
          }
          static private _instance;
      }
      

      并获得您的结果

      int x=AgentDescriptions.Instance.P1;
      

      查看:

      How to restrict user for checking null for singelton instance in C#, .NET?

      我经常将该模式用于配置项或常量项。

      【讨论】:

        【解决方案5】:

        会尝试这样的......

        int p1 = -1; //Or some impossible value.  This could also be a int? and left as null until it is initialized.
        public static int P1
        {
            get //Define only the 'get' of the property for this to make it readonly
            {
                if (p1 == -1)
                   //Insert Code to get & assign the value of p1 from your DB.
                return p1;
            }
        }
        

        【讨论】:

          【解决方案6】:

          您不需要初始化程序(静态构造函数)。如果 AgencyId 是整数,试试这个

          public static class AgentDescriptions  
          { 
             private static readonly Dictionary<int, int> dic
                  = new Dictionary<int, int>();
             public static int GetId(int agencyId)
             {
                 if (!dic.ContainsKey(agencyId))
                      Adic.dd(agencyId, GetIDFromDB(agencyID));
                 return dic[agencyId];
             }
           // ...
          

          并像这样使用它:

             if (something == AgentDescriptions.GetId(agencyId)) 
             //Blah(); 
          

          或者,如果 AgencyId 是一个字符串,或者您想使用“P1”、“P2”等字符串作为键,那么

          public static class AgentDescriptions 
          { 
             private static readonly Dictionary<string, int> dic
                  = new Dictionary<string, int>();
          
             public static int GetId(string agencyId)
             {
                 if (!dic.ContainsKey(agencyId))
                     Adic.dd(agencyId, GetIDFromDB(agencyID));
                 return dic[agencyId];
             }
           // ...
          

          并像这样使用它:

             if (something == AgentDescriptions.GetId("P1") 
             //Blah(); 
          

          如果代理列表是固定的,您可以添加预配置的静态成员来检索这些代理的 Id...

          public static class AgentDescriptions
          {
              private static readonly Dictionary<string, int> dic
                  = new Dictionary<string, int>();
              public static int P1 { get { return GetId("P1"); } }
              public static int P2 { get { return GetId("P2"); } }
              public static int P3 { get { return GetId("P3"); } }
              public static int GetId(string agencyId)
              {
                  if (!dic.ContainsKey(agencyId))
                      dic.Add(agencyId, 12);
                  return dic[agencyId];
              } 
          

          并像这样使用它:

             if (something == AgentDescriptions.P1) 
             //Blah(); 
          

          【讨论】:

          • 在哪里定义或设置机构ID?
          • 如果这是静态的,我认为它总是一样的(如果它可以改变那么你最好不要把它放在静态类中)。因此,如果它是不可变的,要么对其进行硬编码,要么将其放入配置文件中并在另一个静态初始化字段中获取它(如上所示)
          • 如果它可以改变,那么这个类不应该是静态的......你需要完全重新设计它成为一个有状态的实例类,这样你就可以为每个机构拥有一个......或者,让一个静态 Dictionary&lt;int, AgentDescriptions&gt; 类,每个 AgencyId 都有一个成员,在启动时为每个 Agency 初始化,或者在第一次引用该机构时为每个机构初始化...
          • 谢谢查尔斯,我会采用你的方法。我只需要在启动时为每个机构初始化一次。
          【解决方案7】:

          使用像 AgencyID 这样的 UID 意味着您将拥有一个对象的多个实例。静态意味着你只能得到一个对象。删除静态关键字并创建对象的实例。

          【讨论】:

            【解决方案8】:

            由于您试图在静态字段/属性中传递一些值,然后访问它们,我们可能会将静态类属性视为关于 SINGLETON,因为一旦它们被初始化,您就永远不会更改它们(或者至少你不想这样做),所以这就是我的建议。

            【讨论】:

            • 而且大多数情况下它们都是一种气味不是解决方案
            猜你喜欢
            • 1970-01-01
            • 2011-05-06
            • 1970-01-01
            • 1970-01-01
            • 2011-10-07
            • 2011-04-19
            • 2013-01-16
            • 2014-03-14
            • 2014-07-13
            相关资源
            最近更新 更多