C#字段(field)

字段(field)是类中最常见的成员之一。C# 支持静态字段(类型字段)和实例字段,而上一节《C# const》中介绍的常量属于特殊的静态字段。

对于实例字段,其内存在创建实例时动态分配,而对于静态字段,其内存在类型对象创建时分配。

类型对象是类型加载到一个应用程序域(AppDomain) 时创建的。

只读字段

由 readonly (只读)修饰的字段只能在定义时或构造函数中赋值。

如果试图在构造函数之外的地方修改只读字段,就会发生编译错误。

不过,反射可以修改只读字段(实际上,没有什么是反射改不了的)。

只读字段和常量很像,但也有如下区别:

  • 常量兼有只读和静态,所以常量一定是静态的,但只读字段不一定是。
  • 只读字段可以在运行时决定(例如在构造函数中赋值),而常量必须在定义时就赋值。
  • 只读字段可修饰任何类型,常量字段虽然也可以修饰任何类型,但对于非基元类型, 它的值必须为 null,因此没有什么用。

假设直到运行时才知道值(例如通过读取外部数据库),并且希望之后值不会被改变,那么只读字段就很有用。

如果想将只读字段设置为静态的,而且也是直到运行时才知道值, 那么需要使用静态构造函数为其赋值。

注意,即使对于引用类型的只读字段,我们也可以更改引用类型引用对象的值,但是, 我们不能更改引用类型的引用本身。

下面的代码中,我们试图更改一个只读字符串字段的值,但是,更改字符串的值,实质上是在字符串池中新建一个字符串,并将栈上原字符串的变量指向堆中新的字符串,即为更改引用。所以,这是不可以的。

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        a.print();                      //0
        //可以更改引用对象成员的值
        a.field.b = 999;
        a.print();                      //999
        //但是不可以更改引用本身
        //a.field = new B();
        //a.str = "hello";
        Console.ReadKey();
    }
}
class A
{
    public readonly B field;
    public readonly string str;
    public A()
    {
        field = new B();
    }
    public void print()
    {
        Console.WriteLine(field.b);
    }
}
class B
{
    public double b;
}

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/22365.html

(0)
上一篇 2021年7月20日
下一篇 2021年7月20日

相关推荐

发表回复

登录后才能评论