在玩c#时,意识到了一件奇怪的事情。
以下是代码:
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);
// output : Tolgahan
}
}
为什么反思让我们改变只读字段?
问题是“为什么允许通过反射设置”,而不是“如何做”,因此它不是Can I change a private readonly field in C# using reflection?的副本。
答案 0 :(得分:15)
同样,化学定律说没有反应可以导致一个元素的原子变成另一个元素的原子,但是物理定律说它一直在发生。化学是物理学的有限子集,以便将问题简化为更可解决的方式。
反射是这种情况下的物理学,正常的编程就是化学。它以更简单的心态运作。反射允许您绕过那些更简单的规则,让您接触新的流程,但也会带来新的危险。
答案 1 :(得分:4)
因为readonly
与private
一样,可以防范墨菲,而不是马基雅维利*。
我们使用readonly
和private
以及限制我们可以做的事情的其他任何事情,主要是因为我们希望限制更多不正确,不一致或者只是简单的愚蠢事情,而不是我们有用且富有成效的事物
但它仍然只是零和零。如果某些内存设置为数字“42”并且我们通过只读字段访问它,则在创建对象时它不是只读的。没有什么可以阻止它被改变,除了编译器发现“嘿,首先你说你不想改变它,现在你试图改变它,什么给出?这两个决定中的一个肯定是错的”。
现在,没有承诺反思能够改变它,但没有承诺它不会。现在,反射的工作方式和readonly的工作方式意味着你可以改变它。至少,需要花费大量工作(可能需要影响我们的用户以及需要实施该工作的团队的成本)才能阻止那些因为他们认为有这样做而烦恼的人一个很好的理由。
请注意,与反射相关的权限会停止Machiavelli,
*严格来说,墨菲正在谈论我们应该如何设计能够阻止人们意外做出灾难的事情 - readonly
就是一个很好的例子,插头无法以错误的方式插入更好的方式 - 和马基雅维利在教学而不是练习技巧。尽管如此,它仍然没有那么简洁。
答案 2 :(得分:0)
这可能是因为.Net中的反射是以这种方式实现的。我只能猜测它的动机,但它是一个功能强大(但速度慢)的工具,具有很大的灵活性和滥用的可能性。
这并不是实现这种改变的唯一方式,但这种讨论不像主题那样偏离主题和不合适。