C#中的const和readonly关键字

时间:2013-08-03 14:52:54

标签: c# .net oop

我已经读过C#中的const和readonly keyowrds。这些关键字之间的区别之一是const的值在编译时解析,而readonly关键字在运行时解析。虽然我没有机会在我的任何项目中实施它们。所以我想试一试。我创建了mylibrary,我将在其他项目中使用它。 mylibrary中的代码如下:

 namespace MyLibrary
 {
  public class Class1
  {
    public static readonly string MyVar = "Vikram";
    //public readonly string MyVar;
    //public Class1()
    //{
    //    MyVar = "Test";
    //}
  }
}

现在我将在我的其他控制台项目中使用此库作为参考,如下所示

class Program
{
    static void Main(string[] args)
    {
        //MyLibrary.Class1 class1 = new MyLibrary.Class1();
        Console.WriteLine(MyLibrary.Class1.MyVar); // output is vikram
        Console.ReadLine();
        Console.WriteLine(MyLibrary.Class1.MyVar); // changed to Test but still op as  vikram
        Console.ReadLine();
    }
}

现在在这两个writeline之间我将改变我的库中的“MyVar”的值并重新编译它,根据readonly的概念它应该反映在控制台项目中而不重新编译我的主项目。

如果我对readonly关键字的理解错误,请纠正我。

P.S 我已经查看了this链接的答案。在其中一个答案中提到了以下内容

在readonly值的情况下,它就像是对内存位置的引用。该值未被转换为AssemblyB的IL。这意味着如果更新内存位置,程序集B将获取新值而无需重新编译。因此,如果I_RO_VALUE更新为30,您只需要构建AssemblyA。所有客户都不需要重新编译。

任何人都可以解释粗线确切意味着什么。我认为这就是我在我的例子中所做的。

5 个答案:

答案 0 :(得分:3)

您的理解是正确的,但您无法更改已加载的程序集。你必须重新启动程序。

我认为您可以使用反射更改readonly字段。这样可以更容易地测试它。

顺便说一句,只读字段的值必须是运行时值,因为您可以在其上放置任意初始值设定项。 C#编译器无法对其进行硬编码,因为它无法静态地知道运行时值。

答案 1 :(得分:1)

我认为你并不完全理解readonly修饰符的含义。 查看this reference以获取相关信息。

请注意以下一行:

public static readonly string MyVar = "Vikram";

并不意味着每次引用MyVar时都要重新评估它的价值 它只是意味着一旦MyVar的值被设置,它就不会再被更改,只是为了进一步使用它。

例如,以下几行:

public class Class1
{
    public static readonly string MyVar;

    public Class1()
    {
        MyVar = SomeCalculation();
    }

    Console.WriteLine(MyLibrary.Class1.MyVar);
    Console.WriteLine(MyLibrary.Class1.MyVar);
}

只会触发SomeCalculation()一次!

答案 2 :(得分:0)

只读:内存在运行时分配,值在运行时初始化。

常量:它使用“const”关键字。价值在申报时分配。             整个程序中的值将保持不变。例如。 const int i=5;

答案 3 :(得分:0)

  

你只需要构建AssemblyA。所有客户都不需要   重新编译。

汇编A和汇编B。汇编A在某处有const表达式,如:

public const int number = 10;

如果在程序集number中使用此B,编译器将简单地将number变量的“原始”值放在程序集B的元数据中。如果在number中更改A,则B中不会更改任何内容。要在程序集B中更改嵌入值,必须重新编译B。这种行为的好处之一是,无需加载程序集A即可使用程序集B

但是,对于readonly,在此透视图中,它的工作方式与其他所有(实例|类)字段相同。它不像const的静态方式那样工作(const被认为只是类级变量,而不是实例变量)

答案 4 :(得分:0)

我在阅读了一些关于关键字here on my blog

的文章之后写了一篇文章

博客的一些摘录 的常量

  • 在定义时为const字段提供值。
  • 编译器然后将常量值保存在程序集的元数据
  • 常量始终被视为静态成员,而非实例成员。