Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# c中静态构造函数的帮助#_C#_.net - Fatal编程技术网

C# c中静态构造函数的帮助#

C# c中静态构造函数的帮助#,c#,.net,C#,.net,我需要在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 P

我需要在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时都会跳到DB

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

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

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

您不需要初始值设定项(静态构造函数)。如果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];
   }
 // ...
或者,如果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];
   }
 // ...
如果代理列表是固定的,您可以添加预配置的静态成员来检索这些代理的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];
    } 

我想试试这样的

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

为什么这个类是静态的。如果将变量传递给构造函数,则意味着是具有状态的对象的实例,而不是类


我会让变量成为私有成员变量,并且只有get方法可用于它们。然后有一个构造函数,它接受代理ID并设置这两个变量。如果需要维护此类型的单个实例,则使用singleton(类中的静态函数,用于存储对象的单个实例,或者如果还不存在新对象,则创建新对象)。另一方面,如果您需要具有不同代理ID的多个对象,那么您已经有了这样做的机制。

我会这样做:

   if (something == AgentDescriptions.GetId(agencyId)) 
   //Blah(); 
   if (something == AgentDescriptions.GetId("P1") 
   //Blah(); 
   if (something == AgentDescriptions.P1) 
   //Blah(); 
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后抛出异常(或其他任何异常)。

听起来您确实想要一个各种缓存

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];
    }

    ...
公共类代理描述
{
静态字典agentCache=new。。。;
公共静态int GetP1(int agentID)
{
如果(!agentCache.ContainsKey(agentID))
Add(agentID,GetIdFromDB(agencyID));
返回代理缓存[agentID];
}
...

在其他一些问题中也存在类似的单例问题

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;
研究:


我经常在配置或常量项中使用这种模式。

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

使用类似UID的AgencyID意味着您将拥有一个对象的多个实例。静态意味着您只获得一个对象。删除静态关键字并创建对象的实例。

我在何处定义或设置AgencyID?如果这是静态的,我假设它总是相同的(若它可以更改,那个么最好不要把它放在静态类中)。所以若它是不可变的,要么硬编码它,要么把它放在配置文件中,然后在另一个静态初始化器字段中获取它(如上所示)如果可以更改,则该类不应是静态的……您需要完全重新设计该类,使其成为具有状态的实例类,这样您可以为每个代理创建一个实例类……或者,创建一个静态
字典
类,每个代理ID有一个成员,该类在启动时为每个代理初始化,或者为每个代理初始化第一个ti请告诉我该代理是被引用的…谢谢Charles,我将采用您的方法。我只需要在每个代理启动时初始化一次。您不能传递静态构造函数参数。请参阅MSDN:大量代码气味,我真的怀疑您是否需要这样做,我从未有过这样的需求agencyID来自何处?您可以将参数传递给public static void Main()当你调用你的项目时。在Main方法中初始化P1和P2。可能是+1的重复,建议使用单例。另外,我为破坏你完美的1000次重复表示道歉。:/Ug,单例。仍然是+1。只是不喜欢单例。@George Stocker我想说单例是有争议的,但我认为它们比单例更好n原始形式。他们将相当顺利地插入当前的设计,同时允许以后更容易地使用替代品进行替换。几乎达到-1,singlton不是解决方案,尤其是在存在强烈的气味或不理解状态的情况下。这实际上可能是一个单身汉的情况,因为他遵循我将遵循的规则如果我打算使用一个(在对象的整个生命周期中状态保持不变,并且当您实例化第一个实例时,状态对状态没有影响),也就是说,考虑到传入的agencyID,我认为可能还有一些其他问题……而且大多数情况下,它们都是一种气味,而不是解决方案