41

Is this:

public MyClass
{
    public const string SomeString = "SomeValue";
}

worse than this:

public MyClass
{
    public static string SomeString { get{ return "SomeValue";}}
}

Both can be referenced the same way:

if (someString == MyClass.SomeString)
     ...

The second however, has the protection of being a property. But really how much better is this than a const?

I have learned over and over the perils of having public fields. So when I saw some code using these constants on public fields, I immediately set about refactoring them to properties. But halfway through, I got to wondering what benefit it was to have the static properties over the constants.

Any ideas?

Vaccano
  • 4,048

4 Answers4

58

In C# it's very bad for none of the reasons mentioned in this thread.

Public constants in C# get baked into referencing assemblies. Meaning, if you have a SomeOtherClass in a separate assembly referencing SomeString in MyClass, the CIL generated for SomeOtherClass will contain a hardcoded "SomeValue" string.

If you go to redeploy the dll that contains MyClass but not SomeOtherClass and change the const, SomeOtherClass won't contain what you think it will--it will contain the original value.

If you're 100% positive it's a universal constant like Pi, go crazy; otherwise tread carefully.

Here's a better explanation : https://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and-readonly

brian
  • 3,569
  • Your link is about the differences between const and readonly, not about reasons to encapsulate a const in a property. – Oded Jan 31 '12 at 21:24
  • 3
    @Oded, but the same difference is between const and read-only property. const is baked into the calling assembly, read-only property isn't. – svick Jan 31 '12 at 21:27
  • @svick - I was only talking about the linked article. – Oded Jan 31 '12 at 21:28
  • "But halfway through, I got to wondering what benefit it was to have the static properties over the constants." OP clearly did not know this gotcha with constants and since no one had yet pointed it out, I did. Also, look at the second response, it's much more concise and talks specifically about const. – brian Jan 31 '12 at 21:29
  • 1
    This is something I did not know. It is further evidence that public fields are bad. I think even the "safe" example of Pi is a bad idea (What about when a developer wants more or less digits of precision on Pi? And makes the change to the assembly without knowing this issue.) I have 40+ assemblies in my solution and I could see this really biting us if we are not careful. – Vaccano Feb 01 '12 at 18:13
  • 2
    Does this "Copy" happen in any other parts of C#? (ie enums) – Vaccano Feb 01 '12 at 19:35
  • 2
    Yes, the copy does happen. This is not usually an issue, but if your code makes use of the numeric value of an Enum and it is changed in the manner outlined in this question, then that can cause issues. – Vaccano Feb 02 '12 at 21:27
  • 1
    This is one of the main reasons why const in C# is dumb. We need better support for immutables... – KChaloux Oct 01 '13 at 21:29
  • @Vaccano > What about when a developer wants more or less digits of precision on Pi? Fortunately, IEEE754 floating point numbers have a well-defined maximum precision, and it's low enough that you might as well have universal constant numbers use that entire precision. Decimal also has a well-defined precision. You would never need to (or be able to) increase the precision. – Bob Jun 01 '14 at 08:25
  • @Bob - What I meant is that if the original code had: const long Pi = 3.14; and then some other developer came along an updated the that line to be: const long Pi = 3.141592; then the problem would exist. – Vaccano Jun 02 '14 at 21:36
  • This is excellent advice. – Snoop Mar 10 '16 at 21:51
22

Changing a field into a property is a breaking change. You lose binary, source, and reflection compatibility.

In addition:

  • There's more fine-grained access control with properties. Need it to be publicly gettable but really only want it set with protected access? No problem (from C# 2 onwards, at least).
  • Want to break into the debugger whenever the value changes? Just add a breakpoint in the setter.
  • Want to log all access? Just add logging to the getter.
  • Properties are used for data binding; fields aren't.

http://csharpindepth.com/articles/chapter8/propertiesmatter.aspx

All that said, I don't see how constants are really affected by this (especially if you don't need any of the above features), unless your API changes in such a way that they are no longer constants.

Robert Harvey
  • 199,517
12

The perils of public fields is in the fact that they are mutable and that the implementation underlying them is subject to change.

When it comes to a const this is not normally an issue (similarly to public enumerations) - unless you think that the const will end up as mutable and that you will require encapsulation around the accessor at some time (say to log how many times it was looked up), you might as well keep it as a public const.

Oded
  • 53,586
  • 19
  • 167
  • 181
1

A constant is data. Properties imply the possibility of behavior when you so much as "look" at the value.

Bundling behavior (or the future possibility thereof) with constant data is flat out wrong. For most systems it won't really matter, but it can.

Lets say the value is "PI" and used extensively in the system's calculations. Putting it behind properties will force client programmers to program defensively. They must assign the value into a duplicate constant. If they don't dupe-up, the next version the library could have some unwanted "behavior" introduced behind the property. The behavior of the property (if it's in a compiled library) is unknown. Maybe it performs well in test, but there could be hidden code that executes if a special condition is met. This is not a pre-mature optimization. Especially for a real time system people's lives depend on.

The client programmers may even lose the safety of a constant since the language may not allow them assign a property value into their duplicate constant.

Also, when programmers are forced to assign your property value into their own constant, they effectively nullify whatever behavior you were hoping to accomplish with your property.

True constant data does not need or want encapsulation.

Lord Tydus
  • 1,439
  • 1
  • 10
  • 12