简体   繁体   English

没有设置器的C#属性-如何从构造函数获取设置?

[英]C# Property with no setter - how can it get set from constructor?

How come you can set a get-only auto-property from a constructor? 您怎么能从构造函数设置仅获取自动属性? The code below shows how you can set the property from the constructor but using reflection shows that there really isn't a setter behind the scenes. 下面的代码显示了如何从构造函数中设置属性,但是使用反射表明,幕后确实没有设置方法。 How does it get set from the constructor call if the setter method doesn't even exist in the IL? 如果IL中甚至不存在setter方法,如何从构造函数调用中进行设置?

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;
    }
}

A read-only automatically-implemented property is converted by the compiler into a read-only field and a read-only property. 编译器将自动实现的只读属性转换为只读字段和只读属性。 Assignments to the property in the constructor are compiled as assignments to the underlying field. 构造函数中对属性的分配被编译为对基础字段的分配。

So your code here: 所以你的代码在这里:

public class GetOnlyProperty
{
    public string Thing { get; }

    public GetOnlyProperty(string thing)
    {
        Thing = thing;
    }
}

is compiled into IL as if you'd written: 就像您编写的那样被编译为IL:

public class GetOnlyProperty
{
    private readonly string _thing;
    public string Thing => _thing;

    public GetOnlyProperty(string thing)
    {
        _thing = thing;
    }
}

... except that _thing is really given an "unspeakable name" that wouldn't be a valid C# identifier. ...除了_thing确实被赋予了“无法_thing名字”之外,它不是有效的C#标识符。

A read-only property (get only) has a backing readonly field, which as you probably know, can only be set in the constructor. 只读属性(仅获取)具有一个后备readonly字段,您可能知道,该字段只能在构造函数中设置。

hence when you have object Property { get; } 因此,当您拥有object Property { get; } object Property { get; }

this translates to 这转化为

private readonly object _property;
public object get_Property(){return _property;}

and the compiler knows that if you set the property in the constructor to set the field directly 并且编译器知道如果您在构造函数中设置属性以直接设置字段

Because a read-only property should be assigned at a time or another, otherwise its value would always be the default value of the type, and it would be completely useless. 因为应该一次或一次分配只读属性,否则它的值将始终是该类型的默认值,并且将完全无用。

This is what constructors are for (beside other obvious reasons), to assign values to read-only fields. 这是构造函数(除其他明显的原因之外)用于将值分配给只读字段的目的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM