为什么你可以从构造函数中设置get-only auto-property?下面的代码显示了如何从构造函数设置属性,但使用反射显示在幕后确实没有一个setter。如果setter方法甚至不存在于IL中,它是如何从构造函数调用中设置的?
void Main()
{
var obj = new GetOnlyProperty("original value");
Console.WriteLine(obj.Thing); //works, property gets set from ctor
//get the set method with reflection, is it just hidden..?
//nope, null reference exception
typeof(GetOnlyProperty)
.GetProperty("Thing", BindingFlags.Instance | BindingFlags.Public)
.GetSetMethod()
.Invoke(obj, new object[]{"can't set me to this, setter doen't exist!"});
}
public class GetOnlyProperty
{
public string Thing { get; }
public GetOnlyProperty(string thing)
{
Thing = thing;
}
}
答案 0 :(得分:19)
编译器将只读自动实现的属性转换为只读字段和只读属性。构造函数中对属性的赋值将编译为基础字段的赋值。
所以你的代码在这里:
public class GetOnlyProperty
{
public string Thing { get; }
public GetOnlyProperty(string thing)
{
Thing = thing;
}
}
编译成IL,就像你写的那样:
public class GetOnlyProperty
{
private readonly string _thing;
public string Thing => _thing;
public GetOnlyProperty(string thing)
{
_thing = thing;
}
}
...除了_thing
确实给出了一个“不可言喻的名称”,它不是一个有效的C#标识符。
答案 1 :(得分:2)
只读属性(仅限get)有一个支持readonly
字段,您可能知道,只能在构造函数中设置。
因此当你有object Property { get; }
这转化为
private readonly object _property;
public object get_Property(){return _property;}
并且编译器知道如果在构造函数中设置属性以直接设置字段
答案 2 :(得分:0)
因为应该一次指定只读属性,否则它的值将始终是该类型的默认值,并且它将完全无用。
这是构造函数用于(除了其他明显的原因),为只读字段赋值。