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?

3
  • 2
    Public constants used in this way are just fine. Using properties in this way is overkill.
    – Bernard
    Jan 31, 2012 at 20:36
  • 2
    Have you considered using the readonly keyword? ReadOnly gives you the cleaner syntanx of a const without the problems mentioned in many of the posts. Jan 14, 2013 at 17:55
  • Could also do... public static readonly type constantName = 0;
    – Snoop
    Mar 9, 2016 at 22:28

4 Answers 4

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

11
  • 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, 2012 at 21:27
  • 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 1, 2012 at 18:13
  • 2
    Does this "Copy" happen in any other parts of C#? (ie enums)
    – Vaccano
    Feb 1, 2012 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 2, 2012 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 1, 2013 at 21:29
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.

11

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.

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.