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
VSreadonly
values can be computed dynamically but need to be assigned before the constructor exits.. after that it is frozen. const
's are implicitlystatic
. You use aClassName.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' theAssemblyB
's IL. This means that if tomorrow I updateI_CONST_VALUE
to 20,AssemblyB
would still have 2 till I recompile it. - in the case of the
readonly
value, it is like aref
to a memory location. The value is not baked intoAssemblyB
's IL. This means that if the memory location is updated,AssemblyB
gets the new value without recompilation. So ifI_RO_VALUE
is updated to 30, you only need to buildAssemblyA
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
VSreadonly
values can be computed dynamically but need to be assigned before the constructor exits.. after that it is frozen. const
's are implicitlystatic
. You use aClassName.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' theAssemblyB
's IL. This means that if tomorrow I updateI_CONST_VALUE
to 20,AssemblyB
would still have 2 till I recompile it. - in the case of the
readonly
value, it is like aref
to a memory location. The value is not baked intoAssemblyB
's IL. This means that if the memory location is updated,AssemblyB
gets the new value without recompilation. So ifI_RO_VALUE
is updated to 30, you only need to buildAssemblyA
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
VSreadonly
values can be computed dynamically but need to be assigned before the constructor exits.. after that it is frozen. const
's are implicitlystatic
. You use aClassName.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' theAssemblyB
's IL. This means that if tomorrow I updateI_CONST_VALUE
to 20,AssemblyB
would still have 2 till I recompile it. - in the case of the
readonly
value, it is like aref
to a memory location. The value is not baked intoAssemblyB
's IL. This means that if the memory location is updated,AssemblyB
gets the new value without recompilation. So ifI_RO_VALUE
is updated to 30, you only need to buildAssemblyA
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
Generating HTML Email Body in C#
Does Page Reload Ever Cause Post
Parse Email Content from Quoted Reply
How to Avoid Dependency Injection Constructor Madness
Random Number Generator Only Generating One Random Number
Post an HTML Table to Ado.Net Datatable
How to Deserialize Json With C#
What Are Good Ways to Prevent SQL Injection
Why Are Mutable Structs "Evil"
Sending Email in .Net Through Gmail
How to Create an Excel (.Xls and .Xlsx) File in C# Without Installing Microsoft Office
Winform Application Ui Hangs During Long-Running Operation
What Is the Yield Keyword Used For in C#
Difference Between Select and Selectmany
Mvc5 Razor Html.Dropdownlistfor Set Selected When Value Is in Array