How can I set the value of auto property backing fields in a struct constructor?

ε祈祈猫儿з 提交于 2019-12-29 06:38:11

问题


Given a struct like this:

public struct SomeStruct
{
    public SomeStruct(String stringProperty, Int32 intProperty)
    {
        this.StringProperty = stringProperty;
        this.IntProperty = intProperty;
    }

    public String StringProperty { get; set; }
    public Int32 IntProperty { get; set; }
}

Of course, a compiler error is generated that reads The 'this' object cannot be used before all of its fields are assigned to.

Is there a way to assign values to the backing fields or the properties themselves, or do I have to implement properties the old-fashioned way with my own explicit backing fields?


回答1:


Prior to C# 6, you need to use the "this" constructor in this scenario:

public SomeStruct(String stringProperty, Int32 intProperty) : this()
{
    this.StringProperty = stringProperty;
    this.IntProperty = intProperty;
}

Doing this calls the default constructor and by doing so, it initializes all the fields, thus allowing this to be referenced in the custom constructor.


Edit: until C# 6, when this started being legal; however, these days it would be much better as a readonly struct:

public readonly struct SomeStruct
{
    public SomeStruct(string stringProperty, int intProperty)
    {
        this.StringProperty = stringProperty;
        this.IntProperty = intProperty;
    }

    public string StringProperty { get; }
    public int IntProperty { get; }
}



回答2:


If a structure is going to have, and its users will expect it to have, all three of the following characteristics:

  1. Its entire state is encapsulated in some particular fixed set of readable members
  2. An instance may be readily created in which those members have any combination of values which are valid for their respective types.
  3. A default instance of the type should have all of those members set to the default values of their respective types.

the type should expose its members as fields. The above requirements mean a struct won't be able to do anything an exposed-field struct can't do, and will also mean that if code doesn't hit any threading hazards the struct will be able to do anything an exposed-field struct can do, albeit perhaps more slowly and with more threading hazards.

If a struct Foo has fields f1 and f2, and a constructor which sets those fields in that order, and if fooExpr is some sort of expression of type Foo [perhaps a variable, field, array reference, property, or whatever] the statement:

myFoo.f2 = someValue;

will only be allowed in cases where one could legally say

myFoo = new Foo(myFoo.f1, someValue);

and in all circumstances where the first form is allowed and the behavior of the second form has defined semantics, they will behave identically. Thus, trying to "encapsulate" the properties of Foo doesn't really accomplish anything except make the code more cumbersome to write, less clear, and slower to execute.



来源:https://stackoverflow.com/questions/522280/how-can-i-set-the-value-of-auto-property-backing-fields-in-a-struct-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!