Difference Between Const and Readonly in C#

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

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

what is the difference between const, readonly and get in a static class

The member declared as readonly gives the possibility to be changed in the (static) constructor of the class, while the const member cannot be changed at runtime.

Declaring a field as const makes it automatically static, quoting from §10.3.7:

When a field, method, property, event, operator, or constructor
declaration includes a static modifier, it declares a static member.
In addition, a constant or type declaration implicitly declares a
static member.

The third is just a read-only property which happens to always return 5.

You should never use such a property and prefer const members where possible in order to allow the compiler and/or the jitter to perform their optimizations and to help other people reading your code (that property is kind of a WTF to me). The static readonly member has to be used if it is required a constant value initialized during the program start-up (like, for example, the number of cores of a machine).

This is a great example from the C# specs (§10.5.2.1):

A static readonly field is useful when a symbolic name for a constant
value is desired, but when the type of the value is not permitted in a
const declaration, or when the value cannot be computed at
compile-time. In the example

public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) {
red = r;
green = g;
blue = b;
}
}

the Black, White, Red, Green, and Blue members cannot be declared as
const members because their values cannot be computed at compile-time.
However, declaring them static readonly instead has much the same
effect.

And yet another difference (§10.5.2.2):

Constants and readonly fields have different binary versioning
semantics. When an expression references a constant, the value of the
constant is obtained at compile-time, but when an expression
references a readonly field, the value of the field is not obtained
until run-time.

So, summing it up, they are very different even if at a first glance they might look similar and you should use the one which best suits your intent.

const vs. readonly

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)

Static readonly' vs. 'const'

public static readonly fields are a little unusual; public static properties (with only a get) would be more common (perhaps backed by a private static readonly field).

const values are burned directly into the call-site; this is double edged:

  • it is useless if the value is fetched at runtime, perhaps from config
  • if you change the value of a const, you need to rebuild all the clients
  • but it can be faster, as it avoids a method call...
  • ...which might sometimes have been inlined by the JIT anyway

If the value will never change, then const is fine - Zero etc make reasonable consts ;p Other than that, static properties are more common.

difference between ReadOnly and Const?

No, they aren't.

A const field is literal value embedded in the assembly.

Only primitive values (strings and numbers) can be const, and they are evaluated at compile time.

When you reference a const field, the compiler embeds the literal value of the field. Therefore, if use use a const from another assembly, and the other assembly is recompiled with a different value, your assembly will only use the new value if you recompile it against the new version.


A readonly field is a normal field that cannot be changed outside the constructor.

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

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

Is there a difference between private const and private readonly variables in C#?

Well, you can use consts in attributes, since they exist as compile time. You can't predict the value of a static readonly variable, since the .cctor could initialize it from configuration etc.

In terms of usage, constants are burnt into the calling code. This means that if you recompile a library dll to change a public constant, but don't change the consumers, then he consumers will still use the original value. With a readonly variable this won't happen. The flip of this is that constants are (very, very slightly) quicker, since it simply loads the value (rather than having to de-reference it).

Re interning; although you can do this manually, this is most commonly a compiler/runtime feature of literals; if you init a readonly field via a literal:

someField = "abc";

then the "abc" will be interned. If you read it from config, it won't be. Because a constant string must be a literal, it will also be interned, but it is accessed differently: again, reading from the field is a de-reference, rather than a ldstr.

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

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

const vs. static readonly

I don't know about your second item (I would probably use a constant for a software version or an algorithm… constant) but there is one key difference between the two: const can only hold basic types such as string, bool, or numeric types. static readonly can hold any object. So, for example, I often use static readonly to store resources like Bitmap objects. Those cannot be const.



Related Topics



Leave a reply



Submit