5

I got three class files where in constant is declared as

private const string PAGE_SIZE = "PageSize";

Is it good to move this to new file to hold all common constants declared as

public readonly string PageSize = "PageSize";

What are the pros and cons for this?

4 Answers 4

10

There are some important differences between a const and a readonly field:

  1. The const is evaluated at compile time. If you declare the const in a separate assembly that you reference from you application a change to the const will only affect the application if it is recompiled using the updated assembly. To quote from the .NET Design Guidelines for Developing Class Libraries:

    Do use constant fields for constants that will never change.

    For example, the Math class defines E and PI as static constants.

    The compiler inserts the values of const fields directly into the calling code, which means that const values can never be changed without the risk of introducing a compatibility issue.

  2. A readonly field can be initialized at run-time enabling you to perform run-time calculations to compute the value and use. A const can only be declared by a constant expression that can be fully evaluated at compile time. The only reference type that can be const is String.

About your specific question it really depends on how these constants are used. Obviously you shouldn't have multiple definitions of the same constant. Otherwise it is probably easier to understand if the constant is declared "near" where it is used, e.g. in the class or even the method where it is used.

3
  • Am having trouble understanding the first point -- surely if you change the actual value in either case then the assembly needs to be recompiled, and users need to use the recompiled assembly? Commented Aug 25, 2011 at 10:28
  • 1
    @Tim Barrass: If your application use a recompiled assembly at runtime (by loading it) your application will not see any changes to constants in that assembly. You application will use the constants that was defined when it was compiled. If the linked assembly is modified and deployed to say patch your application you face the risk of your application getting "out of sync" with the constants. You application could be a web application and the linked assembly a framework that is updated on the live server without your application being recompiled. Commented Aug 25, 2011 at 11:31
  • Ta; this shouldn't be but is counterintuitive to me, so will have a play later today, thanks The edit helps (compiler inserting value direct). I'd have though that E and PI in a math lib might change, if someone decides that a higher or lower precision is more appropriate ;) But that's pedantry, point of the docs is taken .. Commented Aug 25, 2011 at 13:40
1

Performance considerations aside -

  • In favour: your constants are all centralised in one place.

  • Against: your constants are no longer close to the point at which they're used.

For constants that are shared between classes it makes sense to break them out to a common single class so they're only specified once. However this implies "inappropriate coupling", so it might be that all the logic that uses this constant needs to be in the same class.

1
  • +1 for inappropriate coupling -- might indicate there needs to be a class extracted that the existing three classes then use by composition. Commented Aug 25, 2011 at 10:31
1

The two may have similar practical effects, but they are useful for signalling your intentions.

So, a const value is something that is available to all instances of your class and will never change. A readonly signals that you have a data value that could be different for each instance of you class, but will be immutable once the class is created. Immutability can be a really useful guarantee when you are sharing the instance of the class between different consumers. In passing, in CLR Via C#, Richter prefers readonly public members to properties with only public setters, I'll have to dig it out and remind myself why.

1
  • +1, as I think this is actually a useful partial explanation and can't see why it was downvoted. Although you might want to draw out the difference between the constant-collecting-class being immutable and the individual original classes having immutable constants. The key thing is whether the data is close to point of use or not. Commented Aug 25, 2011 at 10:24
0

It might be that you're optimizing too early.

This might mean losing flexibility by making the constants shared and public -- hard to say without knowing what the existing classes are.

What if PageSize actually needs to vary between them in the future? Does it actually need to be synchronised across all three classes, or is this just a small tweak that seems like a good idea at the moment?

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