Help with static constructor in c#
I need help initializing static readonly variables in c#. I have a class with this signature
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 and P2 are used over and over in the application and I am trying to avoid two things. 1)Magic numbers and 2)trip to the DB every time I need to use P1 and P2.
In the application I am using them in many places in this manner
if (something == AgentDescriptions.P1)
//Blah();
Please help. How can I pass the agencyID in the static cons开发者_运维技巧tructor? If I add another contructor and pass agencyID there, will I have to initialize the class every time I use it? will this mean a trip to the DB every time?
Why is the class static. If you're passing a variable in to the constructor you're implying an instance of an object with state, not a class.
I'd make the variables private member variables with only get methods available for them. Then you have a constructor that takes the agency ID and sets those two variables. If you need to maintain a single instance of this type, then use a singleton (static function in the class that stores a single instance of the object or creates a new object if one doesn't exist yet). On the other hand, if you need multiple objects with different agency IDs, you've already got a mechanism to do that.
I would do it like this:
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);
}
}
If you want to lock it so Initialize can only be called once, then you can easily just use a flag that throws an exception (or whatever) after Initialize has been called.
It really sounds like you want a cache of sorts.
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];
}
...
There was similar singleton issue in some other question here.
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;
}
and get your results with
int x=AgentDescriptions.Instance.P1;
Look into:
How to restrict user for checking null for singelton instance in C#, .NET?
I use that pattern often for configuration or constant items.
would try something like this...
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;
}
}
You don't need an initializer (static constructor). if agencyId is an integer, try This
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];
}
// ...
and use it like this:
if (something == AgentDescriptions.GetId(agencyId))
//Blah();
or, if agencyId is a string, or you want to use strings like "P1", "P2" etc as keys, then
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];
}
// ...
and use it like this:
if (something == AgentDescriptions.GetId("P1")
//Blah();
if the list of Agencies is fixed, you can add preconfigured static members to retrieve the Id for those agencies...
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];
}
and use it like this:
if (something == AgentDescriptions.P1)
//Blah();
Using a UID like AgencyID implies that you are going to have multiple instances of an object. Static means you only get one object. Remove the static keywords and make instances of your object.
Since you are trying to pass some values inside of static fields/properties, and then access them, we may think about static class properties as about SINGLETON, since once they are initialized you never change them (or at least you don't want to do that), so that is what I would suggest.
精彩评论