Gis*_*shu 1214
除了明显的差异
constVS readonly值定义时的值可以动态计算,但需要在构造函数退出之前分配..之后它被冻结.static.您使用ClassName.ConstantName表示法来访问它们.有一个微妙的区别.考虑一个定义的类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;
}
}
Run Code Online (Sandbox Code Playgroud)
AssemblyB引用AssemblyA并在代码中使用这些值.编译时,
const值的情况下,它就像一个find-replace,值2被'烘焙'到AssemblyB'IL'.这意味着如果明天我将来会更新I_CONST_VALUE到20.AssemblyB直到我重新编译它仍然会有2.readonly值的情况下,它就像ref一个内存位置.该值未被烘焙到AssemblyBIL中.这意味着如果更新内存位置,则AssemblyB获取新值而不重新编译.所以如果I_RO_VALUE更新到30,你只需要构建AssemblyA.所有客户端都不需要重新编译.因此,如果您确信常量的值不会改变,请使用a const.
public const int CM_IN_A_METER = 100;
Run Code Online (Sandbox Code Playgroud)
但是如果你有一个可能改变的常数(例如,精确度)......或者当有疑问时,使用a readonly.
public readonly float PI = 3.14;
Run Code Online (Sandbox Code Playgroud)
更新:Aku需要提一下因为他首先指出了这一点.另外我需要插上我学到的东西.. 有效的C# - 比尔瓦格纳
aku*_*aku 266
有一个充满争议的问题!如果从另一个程序集引用常量,则其值将被编译到调用程序集中.这样,当您更新引用的程序集中的常量时,它将不会在调用程序集中更改!
spl*_*tne 151
小智 55
只是要添加,ReadOnly用于引用类型只使引用readonly不是值.例如:
public class Const_V_Readonly
{
public const int I_CONST_VALUE = 2;
public readonly char[] I_RO_VALUE = new Char[]{'a', 'b', 'c'};
public UpdateReadonly()
{
I_RO_VALUE[0] = 'V'; //perfectly legal and will update the value
I_RO_VALUE = new char[]{'V'}; //will cause compiler error
}
}
Run Code Online (Sandbox Code Playgroud)
Mik*_*Two 26
有一个小的陷阱与readonly.可以在构造函数中多次设置只读字段.即使该值在两个不同的链式构造函数中设置,它仍然是允许的.
public class Sample {
private readonly string ro;
public Sample() {
ro = "set";
}
public Sample(string value) : this() {
ro = value; // this works even though it was set in the no-arg ctor
}
}
Run Code Online (Sandbox Code Playgroud)
Suj*_*jit 25
常量成员在编译时定义,不能在运行时更改.常量使用const关键字声明为字段,必须在声明时初始化.
public class MyClass
{
public const double PI1 = 3.14159;
}
Run Code Online (Sandbox Code Playgroud)
甲readonly构件是一样的,因为它代表了一个不变的值的常数.不同之处在于readonly成员可以在运行时,构造函数中初始化,也可以在声明它们时进行初始化.
public class MyClass1
{
public readonly double PI2 = 3.14159;
//or
public readonly double PI3;
public MyClass2()
{
PI3 = 3.14159;
}
}
Run Code Online (Sandbox Code Playgroud)
常量
static(它们是隐式静态的)只读
Whe*_*lie 20
const是一个编译时常量,而readonly允许在运行时计算一个值,并在构造函数或字段初始化程序中设置.因此,'const'始终是常量,但'readonly'只有在分配后才是只读的.
C#团队的Eric Lippert提供了有关不同类型的不变性的更多信息
Chr*_*s S 15
这是另一个链接,演示了const不是版本安全的,或者与引用类型相关.
摘要:
Yea*_*iam 10
只读:可以在运行时通过Ctor更改值.但不是通过成员函数
常数:通过defult静态.价值无法从任何地方改变(Ctor,Function,runtime等no-where)
还有另一个问题:readonly值可以通过反射的"狡猾"代码来改变.
var fi = this.GetType()
.BaseType
.GetField("_someField",
BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, 1);
Run Code Online (Sandbox Code Playgroud)
何时使用const或readonly
const
readonly
App.config,但一旦初始化就无法更改标记为 const 的变量只不过是强类型的 #define 宏,在编译时 const 变量引用被内联文字值替换。因此,只能以这种方式使用某些内置的原始值类型。标记为只读的变量可以在构造函数中在运行时设置,并且它们的只读性也在运行时强制执行。有一些与此相关的较小性能成本,但这意味着您可以对任何类型(甚至引用类型)使用 readonly。
此外,const 变量本质上是静态的,而 readonly 变量可以是特定于实例的(如果需要)。
它们都是常量,但在编译时也可以使用const.这意味着区别的一个方面是您可以使用const变量作为属性构造函数的输入,而不是只读变量.
例:
public static class Text {
public const string ConstDescription = "This can be used.";
public readonly static string ReadonlyDescription = "Cannot be used.";
}
public class Foo
{
[Description(Text.ConstDescription)]
public int BarThatBuilds {
{ get; set; }
}
[Description(Text.ReadOnlyDescription)]
public int BarThatDoesNotBuild {
{ get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
我们办公室的一名团队成员就何时使用const,static和readonly提供了以下指导:
最后要注意的是:const字段是静态的,但反之则不然.
C#.Net 中 const 字段和 readonly 字段之间存在显着差异
const 默认是静态的,需要用常量值初始化,以后不能修改。构造函数中也不允许更改值。它不能与所有数据类型一起使用。对于前日期时间。它不能与 DateTime 数据类型一起使用。
public const DateTime dt = DateTime.Today; //throws compilation error
public const string Name = string.Empty; //throws compilation error
public readonly string Name = string.Empty; //No error, legal
Run Code Online (Sandbox Code Playgroud)
readonly 可以声明为静态,但不是必需的。声明时无需初始化。可以使用构造函数分配或更改其值。因此,它在用作实例类成员时具有优势。两个不同的实例化可能具有不同的只读字段值。对于前-
class A
{
public readonly int Id;
public A(int i)
{
Id = i;
}
}
Run Code Online (Sandbox Code Playgroud)
然后只读字段可以用即时特定值初始化,如下所示:
A objOne = new A(5);
A objTwo = new A(10);
Run Code Online (Sandbox Code Playgroud)
这里,实例 objOne 的 readonly 字段值为 5,而 objTwo 的值为 10。使用 const 是不可能的。