龙空技术网

c# readonly

opendotnet 273

前言:

现时姐妹们对“htmlreadonly”大概比较关切,看官们都想要了解一些“htmlreadonly”的相关知识。那么小编在网上搜集了一些对于“htmlreadonly””的相关内容,希望咱们能喜欢,你们快快来了解一下吧!

在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#中表示一旦字段被初始化,它的值就不能再被改变。这种不可变性在某种程度上可以提高多线程环境下的线程安全性。

对于值类型(如int、bool、double等)或不可变的引用类型(如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 修饰,对象的传递方式(引用或值)都取决于其类型。

标签: #htmlreadonly