“只读”的目的在c#中?(这是一个漏洞吗?)

本文关键字:只读 一个 漏洞 目的在 | 更新日期: 2023-09-27 18:12:42

在c#中创建字段readonly的目的是什么?

它实际上似乎并不能阻止对字段的修改:

public struct Struct
{
    public readonly int Value;
    public Struct(int value)
    {
        this.Value = value;
    }
}
static class Program
{
    static void Main()
    {
        var s = new Struct(1);
        Debug.Assert(s.Value == 1, "Read-only field is 1");
        s = new Struct(2);
        Debug.Assert(s.Value == 2, "Read-only field written!");
    }
}

这是一个漏洞,还是故意的?
考虑到这个字段可以很容易地修改,我什么时候可以从创建一个字段readonly中受益呢?

“只读”的目的在c#中?(这是一个漏洞吗?)

这是一个漏洞,还是故意的?

这是故意的。

它防止字段本身被直接修改(无论是在结构内部还是外部),但这并不意味着你不能用新的Struct值替换变量的整个值(在这种情况下是s)。

对于结构体来说,它肯定没有类那么有用——特别是当"整个值"的替换可能不是原子的时候——但在我看来,它仍然是有用的。

换句话说……你可以把整型看成是不可变的值,对吧?但是这段代码仍然有效:

int x = 10;
x = 20;

这改变了x的值-它不改变10的含义

您的Struct有一个不同的实例。没有覆盖原Structreadonly值。也就是说,变量s被分配了一个Struct,其中Value为1,然后又被分配了一个Value不同的 Struct

readonly的要点是允许在初始化或构造类型时设置字段的值,而不是在事后设置。

如果你尝试:

static void Main()
{
    var s = new Struct(1);
    Debug.Assert(s.Value == 1, "Read-only field is 1");
    s.Value = 2;
    Debug.Assert(s.Value == 2, "Read-only field written!");
}

你会得到一个编译错误- "一个只读字段不能被赋值(除非在构造函数或变量初始化器中)"

允许构造函数或声明写入它们,但不能写入其他对象。

From MSDN: "当字段声明包含只读修饰符时,对声明引入的字段的赋值只能作为声明的一部分或在同一类的构造函数中发生。"

From Microsoft Docs:

只读字段既可以在声明中初始化,也可以在构造函数中初始化。