Automatically implemented property in struct can not be assigned

▼魔方 西西 提交于 2019-11-27 08:02:28

From the C# Specification:

10.7.3 Automatically implemented properties

When a property is specified as an automatically implemented property, a hidden backing field is automatically available for the property, and the accessors are implemented to read from and write to that backing field.

[Deleted]

Because the backing field is inaccessible, it can be read and written only through the property accessors, even within the containing type.

[Deleted]

This restriction also means that definite assignment of struct types with auto-implemented properties can only be achieved using the standard constructor of the struct, since assigning to the property itself requires the struct to be definitely assigned. This means that user-defined constructors must call the default constructor.

So you need this:

struct T 
{
    public T(int u)
        : this()
    { 
        this.U = u;
    }

    public int U { get; private set; }
}

Well, for a start you're creating a mutable struct - that's almost always a really bad idea. Mutable structs can sometimes behave in ways you don't expect. Okay, it's only privately mutable, but the fact that you've written code to mutate it is a bad sign.

The reason for the second error is that you can't use any properties or methods of the struct until all fields have been assigned, so you need to chain to the implicit parameterless constructor:

public T(int u) : this()
{ 
    this.U = 10;
}

The compiler requires that any constructor leaves all the fields definitely assigned (which is why you were getting the first error before; the compiler doesn't "know" that the property assigns the field a value) - by chaining to this(), you're making sure that by the time you get to your constructor body, all the fields are already definitely assigned, and you don't need to worry about it any more.

However, unless you actually want to allow mutation, I suggest you just make it a genuinely read-only property:

struct T 
{
    private readonly int u;

    public T(int u)
    { 
        this.u = 10;
    }

    public int U { get { return u; } }
}

Now it's more obvious that you don't want to mutate it even within the struct itself.

Add a call to the default constructor:

public T(int u) : this() 
{
    this.U = 10;
}

you have to use the default constructor here:

struct T
{
    public int U { get; private set; }

    public T(int u) : this()
    {
        U = 10;
    }


}

From C# 6 this is not an issue anymore and it compiles correctly. Look here

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