专用属性字段出现StackOverflow异常



有人能告诉我为什么我得到下面代码的StackOverflowException吗?

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

如何解决此问题?难道编译器不会自动生成一个后备字段吗?

我想要实现的是返回_VoltageRange加上其自身的10%。

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

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

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

以下是执行私有属性时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       

现在,您可以清楚地看到调用

中递归发生的位置

最新更新