私有属性字段上的StackOverflow异常

时间:2012-08-01 19:11:58

标签: c# properties stack-overflow

有人可以告诉我为什么我会得到StackOverflowException下面的代码?

    private float _voltageRange
    {
        get { return _voltageRange + ((10F/100F)*_voltageRange); }
        set { _voltageRange = value; }
    }

如何解决此问题?是不是编译器会自动生成支持字段?

我想要获得的是_VoltageRange加上自己的10%。

3 个答案:

答案 0 :(得分:11)

你的getter和你的setter都会递归地调用它们。

不,编译器不会自动为您创建支持字段 - 除非您使用这样的自动实现的属性:

public float VoltageRange { get; set; }

每当你提供getter / setter主体时,你必须自己所有

这听起来像你想要的:

private float _voltageRange;
private float VoltageRange
{
    get { return _voltageRange + ((10F/100F)*_voltageRange); }
    set { _voltageRange = value; }
}

或更简单:

private float _voltageRange;
private float VoltageRange
{
    get { return (_voltageRange * 11) / 10; }
    set { _voltageRange = value; }
}

(或者只乘以1.1f,但数据丢失的可能性会更大。)

请注意,这是一个非常奇怪的属性 - 值集与检索的值不同。通常这个:

VoltageRange = VoltageRange;

将是一个无操作。大多数读者都会期待

拥有两个属性可能会更好,例如:

private VoltageRange { get; set; }

private EffectiveVoltageRange { get { return VoltageRange * 1.1f; } }

答案 1 :(得分:1)

将您的代码更改为这样,这将解决您的问题

private float _voltageRange;

public float VoltageRange
{
  get { return _voltageRange + ((10F/100F)*_voltageRange); }
  set { _voltageRange = value; }
}

答案 2 :(得分:0)

以下是执行私有财产时IL的外观:

get__voltageRange:
IL_0000:  nop         
IL_0001:  call        UserQuery.get__voltageRange
IL_0006:  ldc.r4      CD CC CC 3D 
IL_000B:  call        UserQuery.get__voltageRange
IL_0010:  mul         
IL_0011:  add         
IL_0012:  stloc.0     
IL_0013:  br.s        IL_0015
IL_0015:  ldloc.0     
IL_0016:  ret         

set__voltageRange:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  call        UserQuery.set__voltageRange
IL_0007:  nop         
IL_0008:  ret       

您可以清楚地看到调用中发生递归的位置