C# 属性将值设置为自身时如何发生堆栈溢出异常

C# 属性将值设置为自身时如何发生堆栈溢出异常,c#,properties,stack-overflow,C#,Properties,Stack Overflow,堆栈溢出异常是执行堆栈可用的有限内存耗尽时引发的.NET异常错误。这几乎总是由无限递归引起的,最终会导致太多嵌套方法调用 以下代码在尝试设置值时将引发堆栈溢出异常 public String Name { get{return Name;} set{Name = value;} } 我知道引用存储在stackhere中,它的名称和对象存储在HeapString对象中。这个地方的内存使用率有多高?有人能告诉我场景背后发生了什么内部实施细节吗?什么是支持字段的必

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

以下代码在尝试设置值时将引发堆栈溢出异常

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

我知道引用存储在stackhere中,它的名称和对象存储在HeapString对象中。这个地方的内存使用率有多高?有人能告诉我场景背后发生了什么内部实施细节吗?什么是支持字段的必要性?

当您生成getter代码{return Name;}时,您是在递归。怎样当一些代码想要获取Name的值时,getter方法会告诉它,为什么不再次尝试问我?看到问题了吗?当您尝试获取一个值时,它会告诉您需要再次询问自己。一次又一次。再一次

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

此外,更新后的问题会询问setter为什么会导致堆栈溢出。原因和以前差不多;当调用Name的setter时,它会调用自身。简单的引语来解释?Name回应您的代码说,如果您想设置我的值,请再次尝试设置我的值

它在哪里做到的?In Name=value;。您可以尝试设置该值,但您的方法会告诉它重新设置自身。一次又一次。一次又一次

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

使用此

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


在C语言中,属性是一对方法的语法糖:get_PropertyName和set_PropertyName如果属性是只读或只写的,则不会生成相应的方法。您的代码将由编译器进行如下转换:

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

public void set_Name(string value)
{
    set_Name(value);
}
看看getter和setter,您将看到纯递归。
因此,每次您尝试访问属性时,无论是获取还是设置,都将调用递归方法。

虽然此代码有效,但它不会向OP解释此概念。教人钓鱼。您关于堆栈和堆的假设是错误的。有关这种常见误解的解释以及为什么不必关心堆栈与堆的关系,请参阅
public string get_Name()
{
    return get_Name();
}

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