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

本文关键字:支持 字段 初始化 结构 何使用 编译器 | 更新日期: 2023-09-27 18:33:16

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

自动实现的属性"矩形.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; }
}

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

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

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 只能在构造函数中调用,并直接转换为写入只读字段,但没关系......

如果您链式调用默认构造函数(它将默认为您初始化支持字段,满足编译器的要求(,则可以避免该错误。

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

除非您有特殊原因使用自动属性而不是字段,否则只需使用公共字段。 类属性可以做字段不能做的有用事情(例如,支持更新通知(,并且在类类型中使用自动属性开始(而不是字段(将使以后更容易使用真实属性(如果需要这些额外的功能(。 可变结构属性实际上并没有提供与类属性相关的任何优势。 鉴于声明:

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

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