Matthew Scharley
Matthew Scharley

Reputation: 132254

What is happening here? How can I call the default constructor when there is none?

Given the following code:

public struct Foo
{
    public Foo(int bar, int baz) : this()
    {
        Bar = bar; // Err 1, 2
        Baz = baz; // Err 3
    }

    public int Bar { get; private set; }
    public int Baz { get; private set; }
}

What does : this() actually do? There is no default constructor, so what is it calling? Without this addendum, the whole thing crashes with errors.

Error   1   The 'this' object cannot be used before all of its fields are assigned to
Error   2   Backing field for automatically implemented property 'Foo.Bar' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.
Error   3   Backing field for automatically implemented property 'Foo.Baz' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.

Upvotes: 15

Views: 5051

Answers (3)

George Mauer
George Mauer

Reputation: 122052

So why is a struct constructor with no arguments not permitted in C#? This is because structs already contain a default constructor which has no arguments. Keep in mind that this default constructor is part of the .Net framework, therefore it is not visible in our code. The sole purpose of the default constructor is to assign default values to its members.

Basically, all structs have a default constructor already. The situation would be different with a class.

Upvotes: 14

Guffa
Guffa

Reputation: 700222

As you are using the shortcut for properties, you can only access the properties through their setters and getters. However, before all fields has been assigned, you are not allowed to call any of the setters. A workaround for this is to call the parameterless constructor that is created automatically, that initialised the fields. This of course means that you are initialising the fields twice.

When I was faced with this problem a few days ago I just removed the shortcut for properties, and declared the local variables myself so that I could set them in the constructor:

public struct Foo {

   public Foo(int bar, int baz) {
      _bar = bar;
      _baz = baz;
   }

   private int _bar, _baz;

   public int Bar { get { return _bar; } }
   public int Baz { get { return _baz; } }

}

Upvotes: 8

Locksfree
Locksfree

Reputation: 2702

this discusses why they added this extra check.

Upvotes: 4

Related Questions