属性 getter/setter 中的姓名

Property name in getter/setter

我正在创建一些属性并遇到了一个我以前从未见过的场景。

考虑

private double _temperature;
private double _maxTemp;

public double Temperature
{
    get { return _temperature; }
    set { _temperature = value; }
}
public double MaxTemp
{
    get { return _maxTemp; }
    set { _maxTemp = value; }
}
public bool IsTempToHigh
{
    get
    {
        if (_temperature < _maxTemp)
            return true;
        else
            return false;
    }
}

这里没问题,但我有很多这种方式的属性,我将其重写为:

public double Temperature { get; set; }
public double MaxTemp { get; set; }
public bool IsTempToHigh
{
    get
    {
        if (Temperature < MaxTemp)
            return true;
        else
            return false;
    }
}

在我看来,它更简洁了一点,而且似乎也能正常工作。但是,我很紧张地看到或注意到任何人直接在 gettes(或 setters)中使用 属性 名称,因此使用是否安全或可能存在任何陷阱。

还有为什么编译但给出 WhosebugException:

public double Value
{
    get { return Value; }
    set { Value = value; }
}

第一个问题: 是的,我认为您的更改使代码更清晰。使用支持字段的一个有效案例是如果你想要不变性。然后这些字段是只读的,你没有 setters.

第二个问题: 您的 setter 呼叫您的 setter。这叫你的 setter。这叫你的 setter。等等。一段时间后,堆栈变得太大,您会收到错误消息。 :)

您可以轻松地在您的属性中使用其他属性、字段和方法。完全不用担心。

然而,您的第二个代码块一遍又一遍地调用相同的 属性。您正在尝试将自动实现的属性与手写属性混合使用。那是不可能的。

编译器为您生成支持字段(当您使用自动实现的属性时)您必须自己创建它们(手写属性)。

所以要么是这样:

public double Value { get; set; }

或者:

private double _value;
public double Value
{
    get { return _value; }
    set { _value = value; }
}
  1. 在您当前使用数据成员的私有成员函数中使用 属性 名称是安全和好的。

  2. 该代码会引发 Whosebug 异常,因为通过分配给 Value 您实际上是在调用 属性。相反,将基础数据成员的名称更改为 _value:

    public double Value {
        get { return _value; }
        set { _value = value; }
    }
    

如果您的意思是 IsTempTooHigh,那很好(尽管条件是名称的错误方式)。在另一个 属性 中引用一个 属性 是完全有效的,但您需要注意不要使其递归。您的自动实现的属性仍然有支持字段 - 它们只是由编译器为您生成,而不是出现在您的源代码中。

我会在没有 if 的情况下重写你的计算 属性,请注意:

public bool IsTempTooHigh { get { return Temperature >= MaxTemp; } }

或者在 C# 6 中:

public bool IsTempTooHigh => Temperature >= MaxTemp;

至于堆栈溢出,最简单的想象是它们是方法:

public double GetValue()
{
    return GetValue();
}

public void SetValue(double value)
{
    SetValue(value);
}

你能明白为什么调用 那些 中的任何一个会导致堆栈溢出吗?好吧,对于属性来说也是如此——基本上,它们只是带有一些元数据链接它们的方法。

有一个 属性 可以评估另外 2 个属性。当然,您很容易使用一种方法来完成相同的工作。例如。改变

public bool IsTempToHigh
{
    get
    {
        if (_temperature < _maxTemp)
            return true;
        else
            return false;
    }
}

public bool IsTempToHigh()
{
    return _temperature > _maxTemp;
}

(注意:假设这是正确的,我已将您的 < 更改为 >)

您的值出现异常,因为您设置了对象本身。然后这会改变它的值,所以它会尝试再次设置自己....

所以这是错误的...

public double Value
{
    get { return Value; }
    set { Value = value; }
}

但以下任一项 would be ok

public double Value { get; set;}

private double _myVal;

public double MyValue
{
    get{ return _myVal;}
    set{ _myVal = value;}

}