具有自动增量getter的StackOverflowException

时间:2018-01-25 09:48:27

标签: c#

阅读完这个问题后:

Can (a ==1 && a== 2 && a==3) ever evaluate to true?

我试图覆盖getter以在C#中重现所需的行为。

通过这段代码,我获得了我想要做的事情:

public static int MyProperty
{
    get { MyProperty++; return MyProperty; }
    set { MyProperty = value; }
}
static void Main(string[] args)
{
    if (MyProperty == 1 && MyProperty == 2 && MyProperty == 3)
    {
        Console.WriteLine("yohhooo");
    }
}

但是由于我的第一次尝试,我提出了这个问题:

MyProperty++;

由于很多原因,它没有工作,我注意到了一些奇怪的事情:

例如,如果我尝试使用Visual Studio 2017调试它并查看MyProperty初始值,程序会崩溃而不说任何内容。

所以我尝试在不检查值的情况下调试每条指令,并注意到getter中的if是程序问题的原因,它会抛出此错误:

  

System.StackOverflowException

但我不明白为什么。如果我没有错,通过不声明MyProperty的初始值,它应该是0.所以从我的观点来看,如果它执行0 + 1我就看不到问题,为什么要这样做抛出那个例外?

6 个答案:

答案 0 :(得分:6)

您正在阅读自己的吸气剂

public static int MyProperty
{
    get { MyProperty++; return MyProperty; }
    set { MyProperty = value; }
}

调用get,调用get,无限调用get ad - 最终将溢出堆栈。

答案 1 :(得分:3)

首次调用if (MyProperty == 1 ...)的getter将执行MyProperty++,其归结为:

var temp = MyProperty; // get
temp = temp + 1;
MyProperty = temp; // set

所以你看,第一行已经是罪魁祸首,因为它会再次召唤自己。你可以通过使用 F11 反复插入代码来看到这一点。

答案 2 :(得分:2)

在此属性中

public static int MyProperty
{
    get { MyProperty++; return MyProperty; }
    set { MyProperty = value; }
}

为MyProperty分配值时,将调用setter。然后在该setter中再次将值分配给MyProperty,它调用setter等,同样使用getter。

您需要的是这样的支持领域:

private static int myProperty = 0;
public static int MyProperty
{
    get { myProperty++; return myProperty; }
    set { myProperty = value; }
}

答案 3 :(得分:2)

当你拆分"代码"第二个例子不能工作的原因很简单。进入"进行的操作"

public static int MyProperty
{
    get { MyProperty++; return MyProperty; }
    set { MyProperty = value; }
}

专注于getter方面。这里MyProperty++;是您的第一组操作,基本上意味着:

MyProperty 的值 进入MyProperty.get
MyProperty 的值 ...

所以你可以看到,你经常打电话给MyProperty get这就是为什么你会得到这种例外。<\ n> / p>

答案 4 :(得分:1)

你所做的是创建一个无限循环:

public static int MyProperty
{
    get { MyProperty++; return MyProperty; }
    set { MyProperty = value; }
}

将由编译器翻译成以下内容:

private int backingField_MyProperty;
public getMyProperty()
{
    int value = getMyProperty();
    value++;
    setMyProperty(value);
    return value;
}
public setMyProperty(int value) { setMyProeprty(value); }

答案 5 :(得分:0)

因为你的setter会调用它自己,这将导致另一个调用它,这将导致另一个调用....你收到消息,对吧? 这是一个不受欢迎的递归。递归有限制。每个递归调用都将放在堆栈中。在某个时间点,堆栈已满 - 因此也是例外。

这有帮助吗?