如何使用编译器生成的支持字段初始化结构

时间:2013-09-27 21:27:04

标签: c# struct initializer

超简单的问题......如何正确初始化结构上的私有支持字段?我收到编译器错误:

  

自动实现属性“Rectangle.Y”的备用字段   在将控制权返回给调用者之前必须完全分配。   考虑从构造函数中调用默认构造函数   初始化程序。

继承源代码。

public struct Rectangle
{    
    public Rectangle(int x, int y, int width, int height)
    {
        X = x; 
        Y = y; 
        Width = width; 
        Height = height;
    }
    public int Width { get; private set; }
    public int Height { get; private set; }
    public int X { get; private set; }
    public int Y { get; private set; }
}

3 个答案:

答案 0 :(得分:4)

这是在结构中使用自动实现的属性的问题。您需要显式链接到无参数构造函数:

public Rectangle(int x, int y, int width, int height) : this()
{
    X = x; 
    Y = y; 
    Width = width; 
    Height = height;
}

编译器不“知道”设置每个属性将设置相关字段 - 它需要查看所有字段(由于它们是自动生成而无法显式访问)。幸运的是,无参数构造函数可以帮到你。

我个人只是使​​用真正的只读字段和手动属性,请注意:

public struct Rectangle
{    
    private readonly int x, y, width, height;

    public int X { get { return x; } }
    public int Y { get { return y; } }
    public int Width { get { return width; } }
    public int Height{ get { return height; } }

    public Rectangle(int x, int y, int width, int height)
    {
        this.x = x; 
        this.y = y; 
        this.width = width; 
        this.height = height;
    }
}

我希望C#有一种方式来声明“真正”只读自动实现的属性,这样只能在构造函数中调用setter并将其直接转换为只读字段的写入,但不要介意......

答案 1 :(得分:1)

如果你链式调用默认构造函数(默认为你初始化支持字段,满足编译器),你可以避免这个错误。

public Rectangle(int x, int y, int width, int height)
    : this()
{
    // ...

答案 2 :(得分:0)

除非您有使用autoproperties而不是字段的特殊原因,否则只需使用公共字段即可。类属性可以执行字段不能执行的有用操作(例如,支持更新通知),并且在类类型中使用自动属性(而不是字段)将使以后更容易使用真实属性,如果这些额外功能变得必要的话。可变结构属性并不真正提供与类属性相关的任何优点。鉴于声明:

SomeStructure foo,bar;
...
foo = bar;

最后一个语句将捕获所有bar的公共和私有字段的状态,并覆盖所有foo的公共和私有字段的内容,而不会关联任何代码SomeStructure有权阻止它甚至知道它已经发生。如果结构的语义是成员可以保存对其各自类型有效的值的任何组合,则使用属性而不是字段将使某些操作不太方便(例如有争议的初始化),同时基本上不提供保护或其他优点要说的。