Skip to content

Some structs are required to chain the paramerless constructor #8410

@scottdorman

Description

@scottdorman

In the process of upgrading some projects to support .NET Core (by simply moving to the new project.json format) and, once done, the following code failed with compiler error CS0188: The ‘this’ object cannot be used before all of its fields are assigned to.

Prior to the change to .NET Core, this code compiled just fine in a PCL targeting .NET 4.0.

The code in question (edited for brevity) is:

[StructLayout(LayoutKind.Sequential)]
public partial struct Comb : IFormattable, IComparable, IComparable<Comb>, IEquatable<Comb>
{
     public Comb(byte[] array)
     {
         this.a = ((int)array[0] << 24) | ((int)array[1] << 16) | ((int)array[2] << 8) | array[3];
         this.b = (short)(((int)array[4] << 8) | array[5]);
         this.dateTime = this.GetDateTimeOffset(); // <== This line causes the error.
     }

     private DateTimeOffset GetDateTimeOffset()
     {
         var buffer = this.ToByteArray();
         var msecsArray = new byte[]  { ... };

         var days = buffer[6] + (buffer[0] << 8) + (buffer[4] << 16) + (buffer[5] << 24);
         var msecs = BitConverter.ToDouble(msecsArray, 0);
         var date = Comb.MinDate.AddDays(days).AddMilliseconds(msecs * Comb.Accuracy);
         return date;
     }
 }
}

The line (this.dateTime = this.GetDateTimeOffset()) compiles just fine in every version of the Framework except .NET Core.

This is actually easy for me to fix by making sure the constructor chains a call to the parameterless constructor:

public Comb(byte[] array) : this()

I’d argue that the new code is actually more correct and that it’s how the code should have been written in the first place. The issue is that by simply upgrading the project and doing nothing else, I suddenly get a compiler error when there weren’t any before. In fact, there weren’t even any warnings about this before.

Apparently this was similar to an issue with auto properties in structs as well, all the way back to 2009, with the same fix/workaround. According to some of the answers to questions about this on StackOverflow, it was fixed in C#6.

Either way, it’s a regression because what used to compile doesn’t anymore just by upgrading the project format. I'm not certain if it's related to .NET Core or to Roslyn.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions