设置只读字段(这是个错误吗?)

9 浏览
0 Comments

设置只读字段(这是个错误吗?)

只是在使用C#玩耍时,意识到了一件奇怪的事情。\n以下是代码:\n

class Program
{
    static void Main(string[] args)
    {
        System.Diagnostics.Debug.Write(string.Empty);
        typeof(string)
            .GetField("Empty", BindingFlags.Static | BindingFlags.Public)
            .SetValue(null, "Tolgahan");
        Console.WriteLine(string.Empty);
        // 输出:Tolgahan
    }
}

\n为什么反射允许我们修改只读字段?\n


\n问题是“为什么允许通过反射进行设置”,而不是“如何做到”,因此它不是Can I change a private readonly field in C# using reflection?的重复。

0
0 Comments

在.NET中,可以通过反射的方式来设置只读字段。可能是因为.NET中的反射机制是这样实现的。对于为什么要这样实现,我只能猜测,可能是因为反射是一个功能强大但速度较慢的工具,它提供了很大的灵活性和滥用的潜力。

但是,这并不是唯一可以实现这种改变的方式,关于这个问题的进一步主观推测是不合适的,也不应该放在这里讨论。

0
0 Comments

readonly字段的设置(这是一个bug吗?)是因为readonly关键字只是防止Murphy,而不是Machiavelli*。

我们使用readonly、private和其他限制我们所能做的任何东西,主要是因为我们希望限制更多的错误、不一致或纯粹愚蠢的事情,而不是有用和有益的事情。

但它仍然只是二进制的表示。如果某个内存被设置为数字"42",并且我们通过一个readonly字段访问它,那么在对象创建时它是不是readonly的。除了编译器发现"嘿,首先你说你不想改变它,现在你正在试图改变它,怎么回事?这两个决定中肯定有一个是错误的"之外,没有任何阻止它被改变的东西。

现在,没有承诺反射能够改变它,但也没有承诺它不能。目前,反射的工作方式和readonly的工作方式意味着你可以改变它。至少,这将需要很多工作(可能会对我们用户和需要实施这项工作的团队产生影响)才能阻止那些认为自己有充分理由的人去这样做。

请注意,与反射相关的权限确实阻止了Machiavelli的行为,

*Murphy严格来说是在谈论我们应该如何设计事物来防止人们意外做出灾难性的事情-readonly是一个很好的例子,不能以错误的方式插入的插头是更好的-而Machiavelli是在教学而不是实践技巧。尽管这样说不那么简洁。

.s.w.g是Murphy和Machiavelli的什么意思?我不能够声称这是我的功劳。我所知道的最早的类似用法(关于C++中的private)是由Bjarne Stroustrup提出的,尽管我不知道他是否是第一个。

0
0 Comments

这段内容中并未提及具体的技术问题,无法从中整理出"Setting readonly fields (Is this bug?)"这个问题的出现原因和解决方法。建议提供更多相关的上下文信息,以便更好地理解和回答问题。

0