Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does setting the property in the constructor of a struct not work?

I have following code which is not allowed (error below), why?

    struct A
    {
        private int b;

        public A(int x)
        {
            B = x;
        }
        public int B
        {
            get { return b; }
            set { b=value; }
        }

    }

I receive the following error:

The 'this' object cannot be used before all of its fields are assigned to Field 'Test.x' must be fully assigned before control is returned to the caller

like image 784
Mocco Avatar asked Mar 01 '11 11:03

Mocco


1 Answers

A struct's variables all have to be definitely assigned before you can use any methods or properties. There are two possible fixes here:

1) You can explicitly call the parameterless constructor:

public A(int x) : this()
{
    B = x;
}

2) You can use the field instead of the property:

public A(int x)
{
    b = x;
}

Of course the second option only works in your current form - you have to use the first option if you want to change your struct to use an automatic property.

However, importantly, you now have a mutable struct. This is almost always a very bad idea. I would strongly urge you to use something like this instead:

struct A
{
    private readonly int b;

    public A(int x)
    {
        b = x;
    }

    public int B { get { return b; } }
}

EDIT: More details of why the original code doesn't work...

From section 11.3.8 of the C# spec:

If the struct instance constructor doesn't specify a constructor initializer, the this variable corresponds to an out parameter of the struct type

Now initially that won't be definitely assigned, which means you can't execute any member function (including property setters) until all the firsts of the struct being constructed have been definitely assigned. The compiler doesn't know or try to take account of the fact that the property setter doesn't try to read from another field. It's all in aid of avoiding reading from fields which haven't been definitely assigned.

like image 111
Jon Skeet Avatar answered Oct 26 '22 14:10

Jon Skeet