10

Today I found an article where a const field is called compile-time constant while a readonly field is called runtime constant. The two phrases come from 《Effective C#》. I searched in MSDN and the language spec, find nothing about runtime constant.

No offensive but I don't think runtime constant is a proper phrase.

private readonly string foo = "bar";

creates a variable named "foo", whose value is "bar", and the value is readonly, here it is a variable, no business on constant. A readonly variable is still a variable, it can't be a constant. Variable and constant are mutually exclusive.

Maybe this question goes overboard, still I want to listen to others' opinions. What do you think?

Alex
  • 23,004
  • 4
  • 39
  • 73
Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
  • 5
    `readonly` is poor name. It should have been called `immutable`. – leppie Jul 04 '12 at 06:39
  • 1
    I agree that this is not a good choice of terminology in the book. This question, though, is not a good fit for SO because `practical, answerable questions based on actual problems that you face. Chatty, open-ended questions diminish the usefulness of our site and push other questions off the front page` – Eric J. Jul 04 '12 at 06:39
  • It's a "constant" in that it's a value which doesn't and can't change (reflection aside). It's not a constant expression in the C# specification terminology, but I don't think that's much of a problem when this is being described in a book. It really doesn't sound like you've got a *programming* question here... – Jon Skeet Jul 04 '12 at 06:39
  • @JonSkeet: Technically the value can change during the execution of static constructors, can it not? – Eric J. Jul 04 '12 at 06:40
  • readonly means it cannot be assigned to at runtime, hence the "runtime constant" terminology – Alex Jul 04 '12 at 06:41
  • @EricJ.: Yes, that's true - but again, that's something the book may even go into. My point is that it's being used in a context where it's descriptive, rather than as a technical term according to the spec. – Jon Skeet Jul 04 '12 at 06:41
  • @EricJ.: it can be changed in the constructors, not only static constructor. – Cheng Chen Jul 04 '12 at 06:43
  • 2
    The IL terminology is quite nice here: `initonly` – Marc Gravell Jul 04 '12 at 06:58

5 Answers5

10

I believe that author means the following:

Consider example:

public class A {

     public const int a = Compute();         

     private static int Compute(){

          /*some computation and return*/ 
          return some_computed_value;
     }
}

this, will not compile, as you have to have constant value to assign to a . So this is a meaning of compile-time constant .

Instead if you change this to

public class A {

     public readonly int a = Compute();          

     private static int Compute(){
          /*some computation and return*/ 
          return some_computed_value;
     }
}

this will compile. It at runtime makes a computation and assign it to a. This is a meaning of runtime constant

Tigran
  • 61,654
  • 8
  • 86
  • 123
  • But it's not a constant, it's a variable...it's just..you can't change its value after initialization. – Cheng Chen Jul 04 '12 at 06:56
  • 3
    @DannyChen: as others pointed out I believe the book is talking about constant (not changable) value. In first time is becomes such at compile time, in second case it becomes at runtime (after computation). – Tigran Jul 04 '12 at 06:58
6

As you yourself note, that term is not used in the language specification etc. So; blame that book! I would call it a "readonly field", because that is what it is - where the definition of "readonly" here relates to the initializer/constructor, and is limited to regular code. For example, even readonly fields are changeable...

// how to annoy your colleagues...
typeof(string).GetField("Empty").SetValue(null, " ");

(Note, this no longer works on recent CLR versions - the JIT presumably replaces the field-load with a ldstr - but it genuinely did for a very long time)

(more genuine reasons to do this on objects relate to deserialization)

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • I never call it "**** constant",ok...blame the book! – Cheng Chen Jul 04 '12 at 06:52
  • 3
    @Danny when I say "blame the book", I think Jon's point is a good one; perhaps it is simply not making it clear when it is using *descriptive* rather than *formal* terminology – Marc Gravell Jul 04 '12 at 06:54
  • @Jacek unfortunately this no longer works in recent CLRs - I think the JIT detects string.Empty and jumps directly to "ldstr" instead of loading the static field – Marc Gravell Jan 25 '14 at 11:14
  • You can **still** change instance readonlys. Not static ones though. – Bitterblue Apr 14 '14 at 12:38
  • @mini-me oh, you can still change static readonly fields. The problem I am highlighting is that in 4.5 (?) onwards, the JIT rewrites `string.Empty` completely - it never ever ever *actually* looks at the field (except when using reflection, which doesn't use the JIT) – Marc Gravell Apr 14 '14 at 13:57
2

A readonly variable can only be changed in its constructor and can be used on complex objects. A constant variable cannot be changed at runtime, but can only be used on simple types like Int, Double, String. Runtime constant is somewhat accurate, but confuses the issue, there are very explicit differences between a constant and a readonly, and so naming one similar to another is probably not a good idea, even though often they are used to the same purpose.

A quick summary of the differences here

Ryan Amies
  • 4,902
  • 1
  • 21
  • 36
2

I would call readonly a "write once variable", which is checked by the compiler, not at runtime. You could write the field using reflection, so it is not constant at runtime.

Stefan Steinegger
  • 63,782
  • 15
  • 129
  • 193
2

const vs readonly

This a complete resume comparison between const and readonly:

|-----------------------------------------|-----------------------------------------|
|              Constant Field             |             Read-only Field             |
|-----------------------------------------|-----------------------------------------|
| Compile-time constant                   | Run-time constant                       |
|-----------------------------------------|-----------------------------------------|
| Assigned to an expression evaluated at  | Assigned to any valid expression at     |
| compile time                            | runtime                                 |
|-----------------------------------------|-----------------------------------------|
| Assigned on declaration                 | Assigned on declaration or constructor  |
|-----------------------------------------|-----------------------------------------|
| Only number, Boolean or string          | Any data type                           |
|-----------------------------------------|-----------------------------------------|
| Always static                           | Optionally static                       |
|-----------------------------------------|-----------------------------------------|

Explanation

  • Constants are static (no need to instantiate the class to access them).
  • Constants can only be assigned on declaration.
  • Constants are compile-time constant because they are assigned to an expression evaluated at compile time: when they changed, the project should be recompiled to use the new values.
  • Read-Only Fields are variables in a class which hold a value that is initialized (only in the constructor or in the declaration) and then not changed.
  • Read-Only Fields are Runtime constant because they can be assigned to any valid expression at runtime.
  • A Read-Only Field apply to the instance of the object but not the property of that instance. So other code can change the instance property of read-only field.
  • Read-Only Fields are optionally static (if you want to make them shared by all instances).

When to use const and when to use readonly ?

  • Constants are useful when they are of simple type and their values will never be changed.
  • Read-Only Fields are useful when they are initialized from a source (file, database or other codes, ..etc.) but then they will not be changed.
Ala Eddine JEBALI
  • 7,033
  • 6
  • 46
  • 65