getter / setter中的属性名称

时间:2015-03-10 14:01:47

标签: c# properties

我正在创建一些属性,并遇到了我以前见过的情景。

考虑

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; }
}

5 个答案:

答案 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)

  1. 在当前使用数据成员的私有成员函数中使用属性名称是安全的。

  2. 该代码抛出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;}

}