自动属性和结构

Pet*_*r17 10 .net c# struct properties automatic-properties

我想知道以下C#代码:

struct Structure
{
    public Structure(int a, int b)
    {
        PropertyA = a;
        PropertyB = b;
    }
    public int PropertyA { get; set; }
    public int PropertyB { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

它没有编译错误"在将所有字段分配给"之前,不能使用'this'对象.对于类似的类,它正在编译而没有任何问题.

它可以通过重构到以下方式来工作:

struct Structure
{
    private int _propertyA;
    private int _propertyB;

    public Structure(int a, int b)
    {
        _propertyA = a;
        _propertyB = b;
    }

    public int PropertyA
    {
        get { return _propertyA; }
        set { _propertyA = value; }
    }

    public int PropertyB
    {
        get { return _propertyB; }
        set { _propertyB = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我认为将自动属性引入C#的重点是避免编写后来的代码.这是否意味着自动属性与结构无关?

Mar*_*ell 20

在C#6中,这简直就消失了 ; 问题中的代码编译得很好.


虽然Stefan有答案而不是解决问题,但我必须建议你不要使用可变结构 - 它咬你.可变结构是邪恶的.

IMO,这里的"正确"解决方案很简单:

struct Structure
{
    public Structure(int a, int b)
    {
        propertyA = a;
        propertyB = b;
    }
    private readonly int propertyA, propertyB;
    public int PropertyA { get { return propertyA; } }
    public int PropertyB { get { return propertyB; } }
}
Run Code Online (Sandbox Code Playgroud)

  • 我只是使用`PropertyA {get; 私人集; }`.只读取得很少 - 避免多次设置属性几乎总是微不足道的.如果你不使用`readonly`,你仍然使用自动实现的属性,所以问题仍然存在. (3认同)
  • @Joren - 它表达了我们的意图;)并且避免了必须调用`:this()`的烦恼 (3认同)

Ste*_*nev 15

您需要首先调用默认构造函数,如下所示:

struct Structure
{
    public Structure(int a, int b) : this()
    {
        PropertyA = a;
        PropertyB = b;
    }
    public int PropertyA { get; set; }
    public int PropertyB { get; set; }
}
Run Code Online (Sandbox Code Playgroud)


Jor*_*ren 8

正如您所见,PropertyA在构造函数中引用时,您正在访问该this对象,编译器将不允许该对象,因为您的字段尚未初始化.

要解决这个问题,您需要找到一种初始化字段的方法.一种方法是您的示例:如果您不使用自动属性,则字段是显式的,您可以初始化它们.

另一种方法是让构造函数调用另一个初始化字段的构造函数.结构总是隐式地具有无参数构造函数,将其字段初始化为零,因此使用:

public Structure(int a, int b)
    : this()
{
    PropertyA = a;
    PropertyB = b;
}
Run Code Online (Sandbox Code Playgroud)