Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How best to implement publicly accessible constants in C#

Tags:

c#

constants

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.

like image 656
devuxer Avatar asked May 22 '10 17:05

devuxer


2 Answers

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.PI is const. That's not going to change any time soon.) There are some subtle memory implications in doing this over using static 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 readonly field 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.

like image 176
Jon Skeet Avatar answered Oct 16 '22 13:10

Jon Skeet


Consider

public static readonly string myVar = "something";

Reason: when you expose (and then consume elsewhere) a const, the const is embedded in the consuming type's metadata.

A public static readonly isn't, and since it's static readonly, it only costs you for instantiation once, and it is immutable like a const.

like image 44
pelazem Avatar answered Oct 16 '22 13:10

pelazem