const常量与Readonly字段在c#中的10个主要区别 淩亂°似流年 2022-10-24 13:22 97阅读 0赞 在c\#中常量中修饰符使字段或局部变量保持不变。ReadOnly应用于c\#中的字段,在初始化后值是常量。Static ReadOnly使ReadOnly字段具有类成员的特性。(可通过类名访问) 请仔细阅读关于常量和readonly之间的差异的总结,然后我将试着解释后面的每一点。 ### 常量与Readonly字段在c\#中的10个主要区别 ### <table> <thead> <tr> <th>C#中的常量</th> <th>C#中Readonly</th> </tr> </thead> <tbody> <tr> <td>const关键字可以应用于字段或局部变量</td> <td>readonly关键字只应用于字段而不是局部变量</td> </tr> <tr> <td>我们必须在公开的时候分配常量字段</td> <td>我们可以在声明或构造函数时指定readonly字段,而不是在任何其他方法中。</td> </tr> <tr> <td>没有分配内存,因为在编译后,在IL代码中嵌入了常量值</td> <td>为Readonly字段分配的动态内存,可以在我们运行时获得值。</td> </tr> <tr> <td>常量在c#中是默认静态的。只能通过类名访问</td> <td>Readonly属于需要过类实例访问的对象。要使它成为类成员,我们需要在readonly之前添加static关键字。</td> </tr> <tr> <td>我们可以声明如下所构建的(基本类型)数据类型为常量 Boolean,Char, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal和string.</td> <td>一样不变</td> </tr> <tr> <td>值是常量(因为它属于类)</td> <td>根据使用的构造函数(因为它属于类的对象),其值可能会有所不同</td> </tr> <tr> <td>如果我们想要对某些类(非原始类型)声明常量,我们应该将其赋值为null,但是这是没有用的。</td> <td>如果声明一个非基本类型(引用类型),readonly只有引用是不可变的,而不是它包含的对象。(见下面的例子)</td> </tr> <tr> <td>不要使用可能导致dll版本问题时发生变化的const字段(参见示例)</td> <td>当在运行时获得的值时,没有dll版本控制问题 Static ReadOnly字段的Const字段不能作为ref或out参数传递</td> </tr> </tbody> </table> ### C\#中的常量字段或局部变量: ### 在C\#中我们将使用关键字 "*const*" 声明常量字段或局部变量. 当你定义一个常量字段时,它的值必须在声明本身的时候被分配,之后我们不能改变它的值。通过下面的例子来了解它 Public class Program { const int fieldConstant = 10; //字段 static void Main(string[] args) { const int X = 10, Y = 50; //正确的 //局部变量 const int Z = X + Y; //正确的 const int A = X + GettheValue(); // 错误的 } public static int GettheValue() { const int localx=10; return 10; } } 前两行没有任何错误,因为X、Y、Z字段值是在编译时本身进行计算的。但是在第三行中,我们声明了一个变量“A”作为常量,并尝试使用GettheValue()方法在运行时返回值。由于必须在编译时分配常量变量,因此该行不会执行。 > c\#中的 **字段** 是在类或结构中直接声明的变量 在上面的示例中 *fieldConstant* 是一个字段,因为它在程序类中直接声明。 我们可以将局部变量声明为 *const* ,如上面所示的GetTheValue()方法。 以下构建的值类型可以声明为常量:int, long, char, float, double, decimal, bool, byte, short,string变量也可作为常量 我们可以将非基原类型赋给null来定义一个常量。但是,将一个常量引用类型声明为null是没有用的。 const string constantString = "Hi Iam Constant"; //正确的 const Program program = new Program(); //错误的 const Program program1 = null; //正确的 我们不能将一个常量变量声明为静态变量,因为默认情况下,常量被视为静态成员。 ReadonlyConstant r1=new ReadonlyConstant();// 请参阅下面的类声明代码 Console.WriteLine(r1.ynumber); //错误的 Console.WriteLine(ReadonlyConstant.ynumber);//正确的 作为默认静态的常量变量,我们无法从类的实例中访问它。所以我们不能将const值作为ref或out参数传递。 ### C\#中的ReadOnly字段: ### 在C\#中我们可以将字段声明为ReadOnly而不是局部变量。 ReadOnly字段可以在声明的时候进行初始化,或者只能在对象创建时只调用一次的构造函数中进行初始化,而不是在任何其他方法中。 public class ReadonlyConstant { public const int numberOfDays = 7; //字段 public readonly double PI=3.14; //内联初始化 public readonly int znumber; public readonly List<int> readonlyList; public ReadonlyConstant() { znumber= 50;//构造函数初始化 } public ReadonlyConstant(int x) { znumber=100; } public NormalMethod() { //readonly int i=0; 这是错误的 } } 根据使用的构造函数,值可能会有所不同。即,readonly字段属于类的对象。 现在我们将讨论常量和readonly字段之间的区别,正如在第二个点中提到的,常量字段没有分配内存,而值直接嵌入IL代码中。请参阅下面的IL代码图片。 我使用resharper工具查看了上面的示例程序(ReadonlyConstant.cs)的中间语言(IL)代码。 正如您可以看到的IL代码的const字段numberOfdays的值(7)直接嵌入IL代码。其中,readonly字段piValue显示为piValue。该值可在运行时获得。 这就导致了版本控制问题。 [https://blog.51cto.com/kejixiaogege/1972344][https_blog.51cto.com_kejixiaogege_1972344] [https_blog.51cto.com_kejixiaogege_1972344]: https://blog.51cto.com/kejixiaogege/1972344
还没有评论,来说两句吧...