58 lines
1.5 KiB
Markdown
58 lines
1.5 KiB
Markdown
|
# Relaxed rules for auto-properties in structs
|
||
|
|
||
|
Before C# 6.0 you could not write code like this:
|
||
|
|
||
|
```csharp
|
||
|
struct S
|
||
|
{
|
||
|
int X { get; set; }
|
||
|
int Y { get; set; }
|
||
|
public S(int x, int y)
|
||
|
{
|
||
|
this.X = x;
|
||
|
this.Y = y;
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
```none
|
||
|
error CS0188: The 'this' object cannot be used before all of its fields are assigned to
|
||
|
error CS0843: Backing field for automatically implemented property 'S.X' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.
|
||
|
error CS0843: Backing field for automatically implemented property 'S.Y' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer.
|
||
|
```
|
||
|
|
||
|
A workaround was to invoke the default constructor:
|
||
|
|
||
|
```csharp
|
||
|
struct S
|
||
|
{
|
||
|
int X { get; set; }
|
||
|
int Y { get; set; }
|
||
|
public S(int x, int y) : this()
|
||
|
{
|
||
|
this.X = x;
|
||
|
this.Y = y;
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
or to initialize this to the default value:
|
||
|
|
||
|
```csharp
|
||
|
struct S
|
||
|
{
|
||
|
int X { get; set; }
|
||
|
int Y { get; set; }
|
||
|
public S(int x, int y)
|
||
|
{
|
||
|
this = default(S);
|
||
|
this.X = x;
|
||
|
this.Y = y;
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Unfortunately, both methods effectively disabled definite assignment analysis for instance fields for the given constructor.
|
||
|
|
||
|
C# 6.0 relaxes these rules by tracking assignments to instance auto-properties as if they were assignments to their backing fields, so the code in the beginning of this section is now valid.
|