Given the below code, I wonder why referenceValue = ConstantInt;
is valid while referenceValue = StaticInt;
fails to compile.
namespace Demo
{
public class Class1
{
private const int ConstantInt = 42;
private static readonly int StaticInt = 42;
public void DemoMethod(ref uint referenceValue)
{
referenceValue = ConstantInt; // This compiles
referenceValue = StaticInt; // This claims that the source type 'int' cannot be converted to 'unit' implicitly.
}
}
}
Readonly variable cannot be modified at run-time. It can only be initialized or changed in the constructor. Constant variables cannot be modified after declaration. Static members can be accessed using ClassName.
const is used to create a constant at compile time. readonly field value can be changed after declaration. const field value cannot be changed after declaration. readonly fields cannot be defined within a method.
Difference between const and readonlyconst variables can declared in methods ,while readonly fields cannot be declared in methods. const fields cannot be used with static modifier, while readonly fields can be used with static modifier.
A const is a compile-time constant whereas readonly allows a value to be calculated at run-time and set in the constructor or field initializer. So, a 'const' is always constant but 'readonly' is read-only once it is assigned.
There is a minor difference between const and static readonly fields in C#.Net. const must be initialized with value at compile time. const is by default static and needs to be initialized with constant value, which can not be modified later on. It can not be used with all datatypes.
readonly can be declared as static, but not necessary. No need to initialize at the time of declaration. Its value can be assigned or changed using constructor once. So there is a possibility to change value of readonly field once (does not matter, if it is static or not), which is not possible with const.
Readonly fields can be initialized at declaration or in the constructor. Therefore, readonly variables are used for the run-time constants. The constant fields must be initialized at the time of declaration. Therefore, const variables are used for compile-time constants.
Static ReadOnly: A Static Readonly type variable's value can be assigned at runtime or assigned at compile time and changed at runtime. But this variable's value can only be changed in the static constructor. And cannot be changed further. It can change only once at runtime. Reference: c-sharpcorner.
Constants are replaced at compile time with their respective value. So from the compiler perspective this referenceValue = ConstantInt;
is the same as this referenceValue = 42
.
While readonly
fields feel similar, they are not. Their value is not truly known at compile time. They are backed by a static field on the class. Their value can be computed, even modified from a static constructor, so the compiler can't check that the value is within the range of uint
at compile time.
For example:
public class Class1
{
private const int ConstantInt = 42;
private static readonly int StaticInt = 42;
static Class1()
{
StaticInt = -20;
}
public void DemoMethod(ref uint referenceValue)
{
referenceValue = StaticInt; // it's -20
}
}
Edit
As pointed out in the comments not all assignments from constants to variables work, long
constant to int
variable does not work without an explicit cast. This behavior is the same based on the type of the constant, regardless of whether it is a named constant or an inline constant:
private const long ConstantInt = 42;
// Both of these will cause an error:
referenceValue = ConstantInt; // can't be converted implicitly
referenceValue = 42L; // but neither can an inline long constant (the L makes it long)
Because constant fields are evaluated on compile time, while readonly
fields are evaluated on run time. The interpreter in the compiler treats your integers differently than the runtime does.
The compiler recognizes the value and its type and it can do some basic conversion based on that, as it does in this case. Try and see what happens if you set ConstantInt
to a negative number. The compiler will error out. The same is true when you change the type to long
or float
: there is no compiler conversion rule, so it errors out too.
from the doc
The readonly keyword is different from the const keyword. A const field can only be initialized at the declaration of the field. A readonly field can be initialized either at the declaration or in a constructor. Therefore, readonly fields can have different values depending on the constructor used. Also, while a const field is a compile-time constant, the readonly field can be used for runtime constants
as in this line: public static readonly uint l1 = (uint)DateTime.Now.Ticks;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With