ame*_*esh 0 c# stack-overflow properties
堆栈溢出异常是.NET异常(错误),当可用于执行堆栈的有限内存耗尽时,将引发该异常。这几乎总是由无限递归引起的,无限递归最终导致太多的嵌套方法调用。
尝试设置值时,以下代码将引发堆栈溢出异常。
public String Name
{
get{return Name;}
set{Name = value;}
}
Run Code Online (Sandbox Code Playgroud)
我知道引用存储在堆栈中(此处是其名称),对象存储在Heap(字符串对象)中。这个地方发生了过多的内存使用情况?有人能告诉我幕后发生的事情吗(内部实现细节)?支持领域的必要性是什么?
当你编写 getter 的代码时{return Name;}
,你就是在递归。如何?当某些代码想要获取 的值时Name
,你的 getter 方法只是告诉它,“你为什么不尝试再问我一次呢?” 看到问题了吗?当你尝试获取一个值时,它会告诉你需要再次询问自己。然后再次。然后再次!
每次访问该属性并调用 getter 时,都会将一个新条目添加到堆栈中。由于此代码只会告诉其他代码不断尝试,因此堆栈会无限地变得更多占用!(每次调用方法(例如 getter)时,都会将一个条目添加到堆栈中)
另外,您更新的问题询问为什么设置器会导致堆栈溢出。原因和之前差不多;当Name
的 setter 被调用时,它会调用自身。简单引用来解释一下?Name
回复您的代码时说:“如果您想设置我的值,请尝试再次设置我的值?”
它在哪里做到这一点?在Name = value;
。您会尝试设置该值,但您的方法会告诉它再次设置自身。然后再次。然后再次。
我们该如何解决这个问题?正如其他回答者所示,您可以创建另一个变量来存储实际内容。例如,Name
将包含 getter 和 setter 以成功操作数据。但它不会将其存储在自身中,以避免无限递归。它将把它存储在另一个变量中,比如_Name
.
在C#中,property是一对方法的语法糖:get_PropertyName
和set_PropertyName
(如果属性为只读或只写,则不会生成相应的方法)。您的代码将由编译器进行如下转换:
public string get_Name()
{
return get_Name();
}
public void set_Name(string value)
{
set_Name(value);
}
Run Code Online (Sandbox Code Playgroud)
查看getter和setter,您将看到纯递归。因此,每次尝试访问该属性时(无论是获取还是设置),都将调用递归方法。
归档时间: |
|
查看次数: |
288 次 |
最近记录: |