There seem to be three choices for implementing publicly accessible constants in C#. I’m curious if there are any good reasons to choose one over the other or if it’s just a matter of personal preference.
Choice 1 – private field plus property getter
private const string _someConstant = "string that will never change";
public string SomeConstant
{
get { return _someConstant; }
}
Choice 2 – property getter only
public string SomeConstant
{
get { return "string that will never change"; }
}
Choice 3 – public field only
public const string SomeConstant = "string that will never change";
Which do you recommend and why?
Update
Apparently, this has turned into a discussion of whether to use const or static readonly. Not exactly what I intended, but it did teach me that Choice 3 is definitely a bad idea because, if the value of the const changes in a future version, it requires all referencing assemblies to be recompiled.
However, I don’t think anyone has really discussed Choice 2 yet. I’m still curious if there’s any disadvantage with having just a getter that returns a value and nothing else.
Choices 1 and 2 are equivalent, really.
It seems to me there are really three different situations:
You know for certain that the string will never, ever change. In this case it’s reasonable to make it
const. (For example,Math.PIis const. That’s not going to change any time soon.) There are some subtle memory implications in doing this over usingstatic readonly, but they’re very unlikely to affect you. You shouldn’t do this if the value may change and you don’t want to recompile all callers in that situation, for the reasons given elsewhere. Note that for many projects (particularly internal corporate ones) it’s really not a problem to recompile all callers.You think the string might change in future, but you know it will always be a constant within any one version. In this case, a
public static readonlyfield is okay. Bear in mind that it’s fine to do this with strings as they’re immutable, but you shouldn’t do this with any mutable types such as arrays. (Either expose immutable collections or use a property and return a new copy each time.)You think the string might change, and it could even change within the lifetime of a program… for example, “the current date, formatted”. In this case, use a public static read-only property (one with only a getter). Note that changing from a readonly field to a read-only property is a source-compatible change, but not a binary-compatible change – so if you have plumped for my second bullet but then need to change to the third, you need to recompile everything.