Practical Difference between Const & ReadOnly
What is the difference between const and readonly?
Apart from the apparent difference of
- having to declare the value at the time of a definition for a const const 必须在定义的时候声明值
VS
readonly values can be computed dynamically but need to be assigned before the constructor exits.. after that it is frozen. readonly可以动态计算,但是必须在构造函数退出前分配值,之后就被冻结
- 'const's are implicitly static. You use a ClassName.ConstantName notation to access them. const是隐式地static,所以你可以使用 类名.变量名 的符号来访问const变量
apart from除……之外
apparent表面的;显然的
implicitly隐式地
notation符号
There is a subtle difference. Consider a class defined in AssemblyA. const和readonly之间还有一些细微的区别。考虑定义在AssemblyA中的类Const_V_Readonly
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;
}
}
subtle 微妙的;精细的;敏感的;狡猾的;稀薄的
AssemblyB references AssemblyA and uses these values in code. When this is compiled, AssemblyB引用了AssemblyA,并使用了const和readonly的值 ,代码编译之后
- 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'll update I_CONST_VALUE to 20 in the future. AssemblyB would still have 2 till I recompile it.
const的值,像“搜索-替代”一样。const的值2直接被放到了AssemblyB的IL(·NET框架中中间语言)中。这意味着,如果明天我将const的值更新为20。AssemblyB中引用的const仍然为2,除非我重新编译AssemblyB
- 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. All clients do not need to be recompiled.
readonly,就像存储单元(内存)的一个引用。readonly变量的值,没有被直接编译到AssemblyB的IL中。这意味着,如果存储单元被更新了,那么AssemblyB将会获取新的值并且不用重新编译。所以,如果readonly的值被改变为30,你仅仅需要重新编译AssemblyA。而不是所有引用了AssemblyA的客户端需要重新编译。
So if you are confident that the value of the constant won't change use a const. 所以,如果你确信有一个常量不会改变,那么就使用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. 但是,如果你有一个常量可能会改变(比如 :精度) 或者有不确定是否会改变。那么使用readonly
public readonly float PI = 3.14;
Update: Aku needs to get a mention coz he pointed this out first. Also I need to plug where I learned this.. Effective C# - Bill Wagner
doubt 怀疑;疑问;疑惑
const string vs. static readonly string in c#
When you use a const
string, the compiler embeds the string's value at compile-time.
Therefore, if you use a const
value in a different
assembly, then update the original assembly and change the value, the
other assembly won't see the change until you re-compile it.
A static readonly
string is a normal field that gets
looked up at runtime. Therefore, if the field's value is changed in a
different assembly, the changes will be seen as soon as the assembly is
loaded, without recompiling.
This also means that a static readonly
string can use non-constant members, such as Environment.UserName
or DateTime.Now.ToString()
. A const
string can only be initialized using other constants or literals.
Also, a static readonly
string can be set in a static constructor; a const
string can only be initialized inline.
Note that a static string
can be modified; you should use static readonly
instead.
const
should only be used for constants - constants being values that never, ever, ever change.Advantages of using const instead of variables inside methods
The compiler will throw an error if you try to assign a value to a constant, thus possibly preventing you from accidentally changing it.
Also, usually there is a small performance benefit to using constants vs. variables. This has to do with the way they are compiled to the MSIL, per this MSDN magazine Q&A:
Now, wherever myInt is referenced in the code, instead of having to do a "ldloc.0" to get the value from the variable, the MSIL just loads the constant value which is hardcoded into the MSIL. As such, there's usually a small performance and memory advantage to using constants. However, in order to use them you must have the value of the variable at compile time, and any references to this constant at compile time, even if they're in a different assembly, will have this substitution made.
Constants are certainly a useful tool if you know the value at compile time. If you don't, but want to ensure that your variable is set only once, you can use the readonly keyword in C# (which maps to initonly in MSIL) to indicate that the value of the variable can only be set in the constructor; after that, it's an error to change it. This is often used when a field helps to determine the identity of a class, and is often set equal to a constructor parameter.
Defining Local Variable const vs Class const
There is no performance gain in moving the constant into the class. The CLR is smart enough to recognize constants as constant, so as far as performance goes the two are equal. What actually happens when you compile to IL is that the values of the constants are hardcoded into the program by the compiler as literal values.
In other words, a constant is not a referenced memory location. It is not like a variable, it's more like a literal. A constant is a literal synced across multiple locations in your code. So it's up to you - though it's neater programming to limit the scope of the constant to where it is relevant.