【问题标题】:Why would this simple code cause a stack overflow exception?为什么这个简单的代码会导致堆栈溢出异常?
【发布时间】:2011-08-15 10:17:02
【问题描述】:

在该属性的setter方法中抛出了堆栈溢出异常:

public string TimeZone
{
    get
    {
        if (TimeZone == null)
            return "";

        return TimeZone;
    }
    set { TimeZone = value; }
}

“发生'System.StackOverflowException'类型的未处理异常”

我在这里没有看到任何直接的递归。

如果代码有问题,我应该改用什么来纠正它?

【问题讨论】:

  • 如下 jgauffin 所述,当您调用 return TimeZone 时,实际发生的是您再次调用 TimeZone 属性。所以它进入了一个无限循环,总是一次又一次地调用它自己。

标签: c# .net recursion


【解决方案1】:
set { TimeZone = value; }

setter 是递归的。

您必须使用如下字段:

string _timeZone;

public string TimeZone
{
    get
    {
        if (_timeZone== null)
            return "";

        return _timeZone;
    }
    set { _timeZone= value; }
}

【讨论】:

  • 是的(我在代码示例中也更改了它),但我回答了询问为什么 setter 会产生堆栈溢出的问题。
【解决方案2】:

getset 都是通过再次调用自己来递归的。试试这个:

string timeZone;

public string TimeZone
{
    get { return timeZone == null ? string.Empty : timeZone; }
    set { timeZone = value; }
}

【讨论】:

    【解决方案3】:

    试试这个

      public string TimeZone
        {
            get
            {
                if (m_TimeZone == null)
                    return "";
    
                return m_TimeZone;
            }
            set {m_TimeZone = value; }
        }
    

    其中m_TimeZone应该是关联变量

    您正在访问属性 TimeZone 内的相同属性 TimeZone,您应该在其中访问和使用关联变量

    【讨论】:

      【解决方案4】:

      在你访问 getter 本身的 getter 中,这会导致对属性 getter 本身的递归调用

       if (TimeZone == null) 
      

      Setter 也是递归的

      set { TimeZone = value; } 
      

      因此取决于调用代码,无论是 getter 还是 setter,都会由于多次调用属性(get_TimeZone() / set_TimeZone() 底层方法)而导致堆栈溢出。

      所以引入支持字段并在属性中使用它,这是一种常用的技术,我想知道你为什么不知道这么简单的东西。

      【讨论】:

        猜你喜欢
        • 2011-01-13
        • 1970-01-01
        • 2016-02-24
        • 1970-01-01
        • 1970-01-01
        • 2014-12-20
        • 2013-12-30
        • 1970-01-01
        • 2011-12-21
        相关资源
        最近更新 更多