LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C#中readonly特性声明字段只读技术文档

admin
2023年10月30日 11:16 本文热度 555

在C#中,readonly特性用于声明一个只读字段。一个只读字段可以在声明时或在构造函数内部进行初始化,一旦被赋予了初始值,它就不能被改变。

使用

下面是使用 readonly 特性的基本语法:

public readonly int MyField;

您也可以在构造函数中初始化只读字段,如下所示:

public class MyClass
{
    public readonly int MyField;

    public MyClass(int value)
    {
        MyField = value;
    }
}

注意事项

  • 只读字段只能在声明或者构造函数中赋值。
  • 只读字段的值不能更改,相当于常量,但常量在编译时需要初始化,只读字段则在运行时初始化。
  • 只读字段可以具有不同的值,取决于所用的构造函数来创建对象。
  • 静态只读字段在运行时初始化,其初始化发生在静态构造函数中(如果存在)或者在出现此类的任何其他静态成员之前。

注意:对于引用类型,readonly修饰符仅防止修改字段本身的值,而不是防止修改字段引用的对象。换句话说,你不能更改引用字段的指向,但是可以更改该字段指向的对象的属性或方法。

readonly修饰的字段GC如何处理它

垃圾收集器(GC)对 readonly 修饰的字段无特殊处理。只读性质并不影响对象的垃圾回收。

垃圾回收主要基于一个对象是否还被引用来决定是否进行回收。如果一个对象不再被任何其他对象引用,那么它就会被 GC 标记为可回收。当 GC 运行时,这些标记为可回收的对象将被清理掉,释放其占用的内存资源。

而对于 readonly 字段,它仅仅是限制了该字段的修改,也就是说一旦字段被初始化后,字段本身的值是不可以被改变的。然而这并不影响其所引用的对象在内存中的生命周期,也不影响垃圾回收的机制。

如果一个 readonly 字段所引用的对象不再被其他对象引用,那么这个对象同样会被标记为可回收,并在 GC 运行时被清理。

readonly修饰的字段内存分配在哪里

在C#中,readonly关键字修饰的字段的内存分配位置取决于它是否被声明为静态(static)。

  • 如果readonly字段是实例字段(非静态),那么它的内存将会在堆上分配,作为创建对象实例时分配的一部分。每个对象实例都有自己的readonly实例字段副本。
  • 如果readonly字段是静态字段,那么它的内存将会在高频堆(High Frequency Heap)上分配,此处用于存储所有的静态数据。所有实例共享一个readonly静态字段。

无论是静态还是非静态的 readonly 字段,都只能在声明时或在相应的构造函数中初始化。对于静态 readonly 字段,这通常发生在静态构造函数或者第一次引用类之前。对于非静态 readonly 字段,它们在实例构造函数中初始化。

下面是一个代码示例:

public class MyClass
{
    public readonly int InstanceField;  // 在堆上分配内存
    public static readonly int StaticField;  // 在高频堆上分配内存

    public MyClass(int value)
    {
        InstanceField = value;
    }

    // 静态构造函数
    static MyClass()
    {
        StaticField = 10;
    }
}

readonly线程安全

readonly关键字在C#中表示一旦字段被初始化,它的值就不能再被改变。这种不可变性在某种程度上可以提高多线程环境下的线程安全性。

对于值类型(如intbooldouble等)或不可变的引用类型(如string),readonly字段是绝对线程安全的,因为他们的状态一旦初始化就无法改变。

但是,对于可变的引用类型(如列表、字典或自定义类),虽然你无法改变readonly字段本身引用的对象,但你仍然可以修改该对象的内部状态。例如,你可以向一个readonly的列表中添加项目。如果不同的线程试图同时修改这个列表,那么可能会遇到线程安全问题。

以下是一个例子,解释了以上的概念:

public class MyClass
{
    public readonly List<int> MyList = new List<int>();  // 可变引用类型

    // ...其他代码...
    
    public void AddItem(int item)
    {
        // 需要保证线程安全,因为MyList是可变的
        lock (MyList)
        {
            MyList.Add(item);
        }
    }
}

readonly只能保证字段本身不会被改变,而不能保证其引用的对象的状态不被改变。在处理可变的引用类型时,还需要采取额外的同步措施以确保线程安全。

readonly修饰的对象传递的是引用还是实例

无论字段是否被 readonly 修饰,对象的传递方式(引用或值)都取决于其类型。


该文章在 2023/10/30 11:16:25 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved