简体   繁体   中英

Regarding C# Static Readonly members

I have the following situation. There is some very common class in my application that contains a static readonly field called "BinDirectory" that holds the path to the bin directory. Other fields in this class, which are static readonly too, use this value to as a base to their value. On the current version BinDirectory is initialized to hold the directory where the code is running (ie Assembly.GetExecutingAssembly().CodeBase). I want to extend this class to initialize BinDirectory to hold the "TargetDir" from the installer context when it is run from my application installer. I can change BinDirectory to be simply static but I don't want to, since it will make me do lots of changes to a class that is common in my app. Can somebody suggest an elegant solution to this problem?

Make it a property with just the "get" accessor:

public static string BinDirectory
{
    get { return _initialisedBinDirectory; }
}

Then in your static constructor code, initialise the private variable as you need.

EDIT

Delayed load (as per comment):

public static string BinDirectory
{
    get
    {
        if (_initialisedBinDirectory == null)
            // load the variable when needed
        else
            return _initialisedBinDirectory;
    }
}

This way you only load the variable when you need it, and it's re-used whenever you call it again. Hopefully you don't class null as a valid value for it though.

This is what AppConfigs are for. In your AppSettings section, add a new key called BinDirectory . You can re-write your class as:

public static string BinDirectory
{
    get
    {
        return ConfigurationManager.AppSettings["BinDirectory"];
    }
}

Finally, as one of the last steps in your installation process, you can change the BinDirectory to point to any directory you want. So now this value is determined entirely by the installer context.

It sounds like you're loath to change a static readonly field to simply static because it would force you to change the initialization of all of the other static readonly fields in your class.

If that is correct, unfortunately there isn't a whole lot you can do but take the time to make the change. By allowing the BinDirectory field to be set at runtime you are fundamentally changing the initialization sequence of the fields. Your code will need to adapt.

I think the easiest way is to convert to using static readonly properties which do the calculation of the value on the fly.

For example:

public class Values { 
  public static string BinDir;
  public static string OtherDir { 
    get { return Path.Combine(BinDir,@"Some\Other\Path"); } 
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM