I have a Common project inside which I've added my public constants for QueryStringNames.
I know generally constants should be as internal or private but I'd need public constants here as I'd like to allow a global access to the query string names, session keys, etc.
There are 3 solutions that I know of but all of them have an important issue. The caller assembly would contain the copy of my constant which means if I have to change a constant value, I'll have to compile both my Common assembly and the caller assembly!
1) public const string ConstName = "a value";
2) public readonly string ConstName = "a value";
3) To be stored in a public resource file.
What would be the best approach to define public constants in C# apart from storing them in the web.config file (which doesn't have intellisense)?
A constant which is needed in more than one functions can be declared a global constant by declaring it a constant using the reserve word const, initializing it and placing it outside of the body of all the functions, including the main function.
A global constant is a literal value to which you assign a name. Like a global variable, you can access the value of the global constant from any script or 4GL procedure in the application. You set the value for the global constant when you declare it.
Really global (application-level) constants should be in the application's namespace (provided your application is inside it's own namespace, as it should be). For module-level constants, the module's own namespace is the natural place.
The declaration of a global variable occurs only outside the blocks or functions.
It depends. If it is truly a constant that won't change, even in future versions of your code, then const
is fine. Else go with a static readonly
field.
A const
will get embedded into the calling assembly, whereas with static readonly
the calling assembly only contains a reference to the field. This means const
requires recompilation of all dependent code whenever you change the value, whereas public readonly
uses the new value even without recompiling the calling assembly.
If you want to store the "constant" in a config file, but like Intellisense, you can use a property with no public setter. And then fill it from the config file at runtime. But I'd argue that configuration values should not be static
in the first place. For configuration values I'd use a singleton of some sort, preferably the IoC variation and not the Class.Instance
variation. So I'd just define an interface like the following:
interface IMyConfig
{
string Key{get;}
}
And have classes that need this config take it as a constructor parameter:
public MyClass(IMyConfig config)
{
...
}
If you think you'd be changing it and you're worried about having to compile it, then why not use appSettings in the web config file? That's what it's for. If you really need intellisense then you could just put a class in one of the assemblies that reads the config value and exposes it as a property for easier referencing. If it's sensitive data then I wouldn't put it in a config file, I would just compile it anyways since you don't want to compromise your application.
<appSettings>
<add key="myconstant" value="here's the value!" />
</appSettings>
Here's the class to reference that value, which gives you intellisense, ability to change it easily in the future, and without having to recompile anything
public class MyAppConfigSettings
{
public string MyConstant { get; private set; }
public MyAppConfigSettings()
{
MyConstant = ConfigurationManager.AppSettings["myconst"];
}
}
It may not be the answer to your solution but it may give you some other ideas.
If you are activating fxCop (code analysis tool included in Visual studio distribution), you may get sugestion to change constant to become:
public static readonly string ConstName = "a value";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With