我正在尝试在c#中学习readonly
关键字行为。只能在构造函数中分配readonly
字段。但是可以在运行时从即时窗口向readonly
字段分配数据。这是一个错误还是行为?
代码段:
public class Foo
{
public readonly string readOnlyField;
public Foo(string parameter)
{
readOnlyField = parameter;
}
public string returnReadOnlyValue()
{
return readOnlyField;
}
}
class Program
{
static void Main(string[] args)
{
Foo foo = new Foo("Read Only - Init");
Console.WriteLine(foo.returnReadOnlyValue());
//Now Modify data from Immediate window
Console.WriteLine(foo.returnReadOnlyValue());
Console.ReadLine();
}
答案 0 :(得分:2)
这是行为。
Readonly
仅在编译时强制执行
答案 1 :(得分:1)
readonly
只做一件事:表明程序员的意图是永远不会改变有关字段。
因此,程序中任何尝试更改它都会显示程序员的工作问题:当他们标记字段readonly
时它们是不正确的,或者当他们尝试更改字段时它们是不正确的。编译器有助于拒绝编译程序,直到以某种方式解决此问题。
编译器可以理论上将此字段放入某种只读或受保护的内存中(如果这样可用且有效)。它很可能不会这样,因为将它存储在与非readonly
字段相同的堆栈或堆中的某个位置更直接。
因为这意味着它在内存中的某个地方以1和0表示,所以没有什么可以阻止其他东西改变那些1和0,包括通过调试器。您也可以通过.NET代码中的反射来更改值。
最终,为什么不呢?它完成了它的工作。
考虑一个带有独立接地,带电和中性的三针电源插座。如果我试图将其插入,例如地球针插入活孔,这将不合适,因此我不会意外地做一些非常愚蠢的事情。
如果我将插头拆开并重新接线,以便将地线连接到带电插针,我可以将其插入插座并使金属外壳带电。
这不是插头和插座设计中的错误。要么我有充分的理由这样做(无论如何,在技术层面,我能想到的唯一真正的原因是尝试杀人)或者我不顾一切地想成为傻瓜。
同样,如果你改变一个readonly
字段,要么你有充分的理由,要么就是你想要变得愚蠢。你只能这么多地保护自己。
(当然,您可能希望在恶意机器上做一些愚蠢的事情,但这是为了防止反映,如果没有足够的信任或调试过程由其他帐户运行而没有管理员访问权限,以防止)。< / p>
答案 2 :(得分:0)
正如@MitchWheat所说,readonly
仅在编译时强制执行。如果您需要在调试时永远不要更改变量,请改用const
。
MSDN的更多信息。
答案 3 :(得分:0)
我确认以前可以在调试器中分配只读成员,但是显然情况在某些时候已经改变。
今天在VS2015的Immediate Window
中,我得到了:
error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)