我想知道,因为可以使用反射完成很多事情,我可以在构造函数完成执行后更改私有只读字段吗?
(注意:只是好奇心)
public class Foo
{
private readonly int bar;
public Foo(int num)
{
bar = num;
}
public int GetBar()
{
return bar;
}
}
Foo foo = new Foo(123);
Console.WriteLine(foo.GetBar()); // display 123
// reflection code here...
Console.WriteLine(foo.GetBar()); // display 456
Run Code Online (Sandbox Code Playgroud) 问题实际上非常简单.以下代码在其下面引发异常:
class Foo
{
public const StringBuilder BarBuilder = new StringBuilder();
public Foo(){
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
Foo.BarBuilder'的类型为'System.Text.StringBuilder'.除string之外的引用类型的const字段只能用null初始化.
MSDN说这是我理解的,从const视角来说它是有道理的:
常量表达式是一个可以在编译时完全计算的表达式.因此,引用类型常量的唯一可能值是string和null引用.
但是,我没有看到我们使用null常数的原因或原因.那么为什么首先可以定义一个引用类型(除了字符串),const如果它只能被设置为null,如果它是一个故意的决定(我相信它是)那么我们在哪里可以使用常量值和空值?
更新:
当我们想到答案时,请让我们的思维方式不同于"我们有这个,所以为什么不......"背景.
如果我要改变它的值bool.TrueString,我会用反射来做:
typeof(bool).GetField("TrueString", BindingFlags.Public | BindingFlags.Static).SetValue(null, "Yes");
Console.WriteLine(bool.TrueString); // Outputs "Yes"
Run Code Online (Sandbox Code Playgroud)
但是,我无法改变,例如Type.Delimiter:
typeof(Type).GetField("Delimiter", BindingFlags.Public | BindingFlags.Static).SetValue(null, '-');
Console.WriteLine(Type.Delimiter); // Outputs "."
Run Code Online (Sandbox Code Playgroud)
为什么是这样?