当属性将值设置为Itself时,如何发生堆栈溢出异常

时间:2013-12-04 05:02:06

标签: c# properties stack-overflow

  

堆栈溢出异常是当执行堆栈可用的有限内存耗尽时引发的.NET异常(错误)。这几乎总是由无限递归引起,最终导致嵌套方法调用过多。

以下代码在尝试设置值时会抛出堆栈溢出异常。

  public String Name
  {
      get{return Name;}
      set{Name = value;}
  }

我知道引用存储在堆栈中(此处为其名称),对象存储在堆(String对象)中。这个地方的内存使用量是多少?谁能告诉我幕后发生的事情(内部实施细节)?支持领域的必要性是什么?

3 个答案:

答案 0 :(得分:4)

当您创建getter的代码{return Name;}时,您正在递归。怎么样?当某些代码想要获得Name的值时,您的getter方法只会告诉它,“为什么不再尝试再问我一次?”查看问题?当你尝试获得一个值时,它会告诉你需要再次问自己。然后再次。再一次!

每次访问属性并调用getter时,都会向堆栈添加一个新条目。由于这段代码只会告诉其他代码不断尝试,堆栈无限地变得更加占用! (每当你调用一个方法时,比如你的getter,一个条目被添加到堆栈中)

此外,您更新的问题询问为什么setter会导致堆栈溢出。这和以前几乎一样; 当调用Name的setter时,它会自行调用。简单的引用来解释? Name在回复您的代码时说:“如果您想设置我的价值,请尝试重新设置我的价值?”

它在哪里这样做?在Name = value;。你会尝试设置值,但你的方法会告诉它再次设置自己。然后再次。再一次。

我们如何解决这个问题?正如另一个回答者所示,您可以创建另一个存储实际内容的变量。例如,Name将包含成功操作数据的getter和setter。但它不会将其存储在自身中,以避免无限递归。它会将其存储在另一个变量中,例如_Name

答案 1 :(得分:3)

在C#中,property是一对方法的语法糖:get_PropertyNameset_PropertyName(如果属性是只读或只写,则不会生成相应的方法)。您的代码将由编译器转换为:

public string get_Name()
{
    return get_Name();
}

public void set_Name(string value)
{
    set_Name(value);
}

看看getter和setter,你会看到纯粹的递归。 因此,每次您尝试访问该属性(无论是获取还是设置),您都将调用递归方法。

答案 2 :(得分:0)

使用此

string _name;
public string Name{
   get{ return _name; }
   set{ _name=value; }
}

OR

public string Name{get;set;}