属性 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; }
}
在您当前使用数据成员的私有成员函数中使用 属性 名称是安全和好的。
该代码会引发 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;}
}
我正在创建一些属性并遇到了一个我以前从未见过的场景。
考虑
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; }
}
在您当前使用数据成员的私有成员函数中使用 属性 名称是安全和好的。
该代码会引发 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;}
}