Asked  7 Months ago    Answers:  5   Viewed   40 times

What is the difference between const and readonly in C#?

When would you use one over the other?



Apart from the apparent difference of

  • having to declare the value at the time of a definition for a const VS readonly values can be computed dynamically but need to be assigned before the constructor exits.. after that it is frozen.
  • const's are implicitly static. You use a ClassName.ConstantName notation to access them.

There is a subtle difference. Consider a class defined in AssemblyA.

public class Const_V_Readonly
  public const int I_CONST_VALUE = 2;
  public readonly int I_RO_VALUE;
  public Const_V_Readonly()
     I_RO_VALUE = 3;

AssemblyB references AssemblyA and uses these values in code. When this is compiled:

  • in the case of the const value, it is like a find-replace. The value 2 is 'baked into' the AssemblyB's IL. This means that if tomorrow I update I_CONST_VALUE to 20, AssemblyB would still have 2 till I recompile it.
  • in the case of the readonly value, it is like a ref to a memory location. The value is not baked into AssemblyB's IL. This means that if the memory location is updated, AssemblyB gets the new value without recompilation. So if I_RO_VALUE is updated to 30, you only need to build AssemblyA and all clients do not need to be recompiled.

So if you are confident that the value of the constant won't change, use a const.

public const int CM_IN_A_METER = 100;

But if you have a constant that may change (e.g. w.r.t. precision).. or when in doubt, use a readonly.

public readonly float PI = 3.14;

Update: Aku needs to get a mention because he pointed this out first. Also I need to plug where I learned this: Effective C# - Bill Wagner

Tuesday, June 1, 2021
answered 7 Months ago

const fields can only hold value types or System.String. They must be immutable and resolvable at compile-time.

static readonly fields can and generally do hold reference types, which (other than strings) can only be created at runtime. These can (but shouldn't) be mutable types; the only thing that cannot change is the reference itself.

If you need to maintain a "constant" set of instances that are reference types, you generally do it with a set of public static readonly fields, such as the members of System.Drawing.SystemColors.

Last but not least, initialization of a readonly field can be deferred until the execution of a constructor, which means that it even though it can only be written to once, it does not always have to be initialized with the exact same value. True constants declared with const can only ever have a single value (specified at compile time).

Wednesday, July 28, 2021
answered 5 Months ago

Something that is const cannot be mutated via that reference but could be mutated by a mutable reference to the same data. Something that is immutable can't be mutated by any reference to that data. So, if you have

const C c = foo();

then you know that you cannot mutate the object referred to by c through c, but other references to the object referred to by c may exist in your code, and if they're mutable, they could mutate it and therefore change what c sees. But if you have

immutable C c = foo();

then you know that it's not possible for the object referred to by c to change. Once an immutable object has been constructed, it's illegal for it to be mutated, and unless you subvert the type system via casting, it's not even possible to have a mutable reference to an immutable object. And since immutable objects can be put into read-only memory if the compiler chooses to, you could actually get segfaults and the like if you ever tried to cast away immutable and mutate the object. The same goes for const, since a const reference could actually refer to an immutable object. Casting away either const or immutable and then mutating the then mutable object is undefined behavior and should basically never be done.

And since an immutable object can never be mutated even by another reference, reading an immutable object from multiple threads is completely thread-safe. So, immutable objects are implicitly shared across threads, whereas everything else which isn't explicitly marked with shared is considered thread-local. immutable also provides better optimization opportunities to the compiler than const does, because it's guaranteed to never change, whereas a const object can change through another reference to the same data.

For value types, there isn't really much difference between const and immutable (since you can't have mutable references to non-mutable value types), but for reference types, there is a significant difference.

Monday, August 2, 2021
Mawg says reinstate Monica
answered 5 Months ago

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)

Thursday, August 12, 2021
answered 4 Months ago

With an ArrayList you are fairly limited because there is no readonly non-generic collection class in the BCL. The quick and dirty solution is to return a type of IEnumerable.

   public IEnumerable MyList
       get { return mMyList;}

This won't actually prevent someone from casting to ArrayList but it won't allow edits by default either

You can return an effectively readonly list by calling ArrayList.ReadOnly. However it's return type is an ArrayList so the user would still be able to compile with .Add but it would produce a runtime error.

Saturday, September 25, 2021
Anders Brohäll
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :