为什么不允许只有一个带有主体的访问器而不是两个?

Why is it not allowed to have only one accessor with a body instead of two?

假设我有这个 属性:

    public int Money
    {
       get;
       set{
         Money = value;
       }
    }

编译不通过,说get访问器必须有一个主体,因为它没有被标记为abstract、extern或partial。如果我向它添加一个正文和 return 金钱 属性,就像这样:

    public int Money
    {
       get{
         return Money;
       }
       set{
         Money = value;
       }
    }

..我手上有一个无限循环,我的程序会抛出堆栈溢出异常。

所以我的问题最终归结为:有没有一种方法可以保留 get/set 访问器,return get 中的当前值而不创建无限循环,并且仍然有一个主体设置访问器?

要么使用:

public int Money { get; set; }

或者,如果您确实需要访问器主体,则需要使用支持字段:

private int _money;
public int Money
{
    get { return _money; }
    set { _money = value; }
}

但是,只有当您需要在使用 getter 或 setter 时执行一些额外的逻辑(例如引发事件)时才使用后者。

此外,后者或多或少是编译器自动为您生成的,它可以确保一致地使用支持字段。

如果您只提供一个主体,则很难定义它的行为方式:毕竟您无权访问代码中生成的支持字段,因此整个想法没有意义。

如果您为其中一个访问器声明了一个主体,您将不再处理自动实现的 属性,并且还需要实现另一个访问器。

这是自动实现的 属性:

public int Foo { get; set; }

这将在编译时生成一个支持字段。它将在 IL 中表示类似这样的内容:

private int BackingField_Foo;
public int Foo
{
    get { return BackingField_Foo; }
    set { BackingField_Foo = value; }
}

在自动实现的情况下 属性,编译器会生成该字段,因此它知道在哪里读取和写入值 - 但您无法访问它。

现在,如果您自己实现其中一个访问器,自己写入自定义字段,它不再是自动实现的 属性,因此您还必须实现另一个访问器(只要你声明它;你可以创建一个常规的只读或只写 属性 就好了)。

您当前的代码会抛出 WhosebugExceptions,因为访问器会无限期地访问它们自己。

另见 Correct use of C# properties

您可以执行以下操作之一:

// 1. a public variable
public int Money;

// 2. an auto-implemented, or implicit property (very much like the above)
public int Money { get; set; }

// 3. An explicit property declaration with a private variable
private int _money;

public int Money {
    get {return _money;}
    set {
        _money = value;

        // possibly do something else here
    }
}