33

Const is baked into the client code. Readonly isn't. But const is faster. May be only slightly though.

The question is, is there ever any scenario where you should prefer const over readonly? Or to rephrase, are we not practically always better off using a readonly instead of a const (keeping in mind the above-said baking thing)?

11 Answers 11

39

I believe the only time "const" is appropriate is when there is a spec that you're coding against that is more durable than the program you're writing. For instance, if you're implementing the HTTP protocol, having a const member for "GET" is appropriate because that will never change, and clients can certainly hard-code that into their compiled apps without worrying that you'll need to change the value later.

If there's any chance at all you need to change the value in future versions, don't use const.

Oh! And never assume const is faster than a readonly field unless you've measured it. There are JIT optimizations that may make it so it's actually exactly the same.

5
  • 2
    "If there's any chance at all you need to change the value in future versions, don't use const." I'm not following your logic. Part of the point of a constant is that you can change it in a future version.
    – Powerlord
    Commented Feb 17, 2009 at 19:02
  • 19
    If a constant is any more public than "internal" (or if its just internal but you have InternalsVisibleTo), then IL compilers are allowed to copy the constant value into referencing assemblies. This means if you ship a new version and change the constant, you're now out of sync with your consumers. Commented Feb 17, 2009 at 21:26
  • 1
    @AndrewArnott Thanks for that last bit of clarification, I dare say that's a rather important point!
    – AgentKnopf
    Commented May 14, 2013 at 10:50
  • I've moved somewhere where the coding standards seem to favour consts where possible. Am I correct in thinking this is okay if you're not writing a library to be consumed? i.e the application you're writing has consts but it is ultimately the deployed application. Commented Jan 7, 2020 at 12:14
  • Sure. If what you're building only deploys and is never linked into something else that might live longer than what you're building, you're fine. Commented Jan 23, 2020 at 19:01
16

Const vs readonly:

A quick synopsis on the differences between 'const' and 'readonly' in C#: 'const':

  • Can't be static.
  • Value is evaluated at compile time.
  • Initiailized at declaration only.

'readonly':

  • Can be either instance-level or static.
  • Value is evaluated at run time.
  • Can be initialized in declaration or by code in the constructor.

The above states const can't be static. That is a misnomer. They can't have the static keyword applied because they are already static.

So you use const for static items that you want evaluated at compile-time.

0
5

You can use a const value as a case in a switch statement, fwiw.

4

I typically only use const for things that I know will never ever change such as the speed of light in a vacuum.

I prefer readonly for things that could potentially change. This way I only need to recompile one dll if a change happens. An exception to this rule of thumb is if the variable is private/protected/friendly to its own assembly. In those cases it is safe to use const.

0
3

readonly is useful when the initialization is not straight forward.
const can be used when you are sure of the value before it is compiled.

In a way, readonly is a runtime const & const is a compile time constant value.

EDIT: If you look at some code using www.koders.com, you will find that there is a use of readonly where const could have been used. I think, the reason behind that could be it is modifiable in the constructor (if need be). In case of const (especially public), you have a chance of breaking the client code dependent on your code.

2

const cannot be used for classes or structures (except for string constants and null, as Mr. Skeet pointed out), only for value types and are accessed as static fields. A const's value is set at compile time and must be set when it is declared.

readonly can be used for anything except enumerations and can be either a static or instance field. A readonly's value is set at runtime and can be set differently depending on which constructor is called.

Here's a good page for an overview of the const, readonly and static keywords.

2
  • Flat out incorrect. I think you've confused your languages - this is C++.
    – Arafangion
    Commented Feb 17, 2009 at 5:14
  • 1
    const can be used with reference types - it's just that the only reference type constants are string constants and null.
    – Jon Skeet
    Commented Feb 17, 2009 at 7:32
1

You should prefer modifier that are tested at compile time over modifier that are tested during runtime (in this context const over readonly). And you should always use the modifiers that support the semantic you need. If something isn't meant to be modified - protect it or someone will write something to it (by accident or by ignorance).

0

You should use const whenever you can set the value in the declaration and don't have to wait for the constructor.

1
  • There are definitely other caveats to consider here. See also here.
    – Marc L.
    Commented Oct 29, 2018 at 15:45
0

A good use of const is for keys of key/value pairs. For example, if you are still using AppSetting (instead of ApplicationSettings), it doesn't really make sense to load the name of the key to a configuration setting. If it is used in several place, stick the Key in a const.

0

Use const when your fields are of simple type (number, Boolean or string) and their values will never be changed. If you change their values, the project should be recompiled.

Use readonly fields when they are initialized from another source (file, database or other codes, ..etc.) but then they will not be changed.

Use static readonly fields when you want to make them shared by all instances.

0

A particular use I've found for consts is reusable "magic" strings used in attributes, since they can only be consts, you cannot use static readonlys.

My particular use case was the ASP.NET authorisation attribute

[Authorize(Roles = Roles.FirstParty)]

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