我正在创建一些属性,并遇到了我以前见过的情景。
考虑
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(或setter)中使用属性名称,因此使用它是否安全,或者是否存在任何陷阱。
为什么这会编译但是会产生StackOverflowException:
public double Value
{
get { return Value; }
set { Value = value; }
}
答案 0 :(得分:7)
如果你的意思是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);
}
你能看出为什么调用那些中的任何一个会导致堆栈溢出吗?嗯,它对于属性来说是一样的 - 它们只是带有一些元数据链接它们的方法,基本上。
答案 1 :(得分:2)
第一个问题: 是的,您的更改使我认为代码更清晰。如果您想要不变性,使用支持字段的有效案例。这些字段是只读的,你没有制定者。
第二个问题: 你的二传手叫你的二传手。哪个叫你的二传手。哪个叫你的二传手。等等。过了一会儿,堆栈变得太大而你得到了错误。 :)
答案 2 :(得分:2)
您可以轻松使用属性中的其他属性,字段和方法。不用担心。
然而,您的第二个代码块一遍又一遍地调用相同的属性。您正在尝试将自动实现的属性与手写属性混合使用。这是不可能的。
或编译器为您生成支持字段(当您使用自动实现的属性时)或您必须自己创建它们(手写属性)。
所以它是:
public double Value { get; set; }
或者:
private double _value;
public double Value
{
get { return _value; }
set { _value = value; }
}
答案 3 :(得分:1)
在当前使用数据成员的私有成员函数中使用属性名称是安全的。
该代码抛出StackOverFlow异常,因为通过分配给Value
,您实际上正在调用该属性。而是将基础数据成员的名称更改为_value
:
public double Value {
get { return _value; }
set { _value = value; }
}
答案 4 :(得分:1)
拥有一个评估其他2个属性的属性是很好的。当然,您可以轻松使用某种方法来完成同样的工作。例如。改变
public bool IsTempToHigh
{
get
{
if (_temperature < _maxTemp)
return true;
else
return false;
}
}
到
public bool IsTempToHigh()
{
return _temperature > _maxTemp;
}
(注意:我已将您的&lt; to&gt;更改为假设这是正确的)
您的值有异常,因为您设置了对象本身。这会改变它的值,所以它试图再次设置自己......
所以这是错误的......
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;}
}