这导致了StackOverFlow错误,我知道为什么,但我想了解更多关于原因的详细信息,并且是我应该如何处理它的解决方案。好的,首先,当我尝试为属性赋值时,以下代码会导致StackOverFlow错误:
private List<Albums> albums
{
get
{
if (Session["albums"] != null)
return (List<Albums>)Session["albums"];
else
return AlbumCollection.GetAlbums();
}
set
{
albums = value;
Session["albums"] = albums;
}
}
为解决上述问题,我更改了属性的名称,并添加了另一个变量来保存解决StackOverFlow问题的属性值:
private List<Albums> albums = null;
private List<Albums> Albums
{
get
{
if (Session["albums"] != null)
return (List<Albums>)Session["albums"];
else
return AlbumCollection.GetAlbums();
}
set
{
albums = value;
Session["albums"] = albums;
}
}
另外,我是否正确设置了setter,分配了值,然后将Session [“albums”]分配给相册中的值?我可以刚刚完成,会话[“专辑”] =值而不是吗?
答案 0 :(得分:16)
因为在你的setter中,你正在调用 setter ,它会进入setter,然后调用...... setter ......和......
set
{
albums = value; // < --- This line calls itself again..
Session["albums"] = albums;
}
您需要做的只是使用Session [“albums”]作为值的持久存储...您不需要私有字段 - 这只是创建值的冗余副本。完全消除它,然后放......
private List<Albums> Albums
{
get
{
if (Session["albums"] != null)
return (List<Albums>) Session["albums"];
else
return (Session["albums"] = AlbumCollection.GetAlbums());
}
set
{
Session["albums"] = value;
}
}
在某些没有持久存储的情况下,公共属性只有一个私有成员支持字段是完全可以接受的。
有关C#属性的更多信息,请查看MSDN tutorial。
答案 1 :(得分:11)
你正在重新分配财产本身。
在您的情况下,您只使用会话。
所以这应该没问题
private List<Albums> albums
{
get
{
if (Session["albums"] == null)
Session["albums"] = AlbumCollection.GetAlbums();
return (List<Albums>)Session["albums"];
}
set
{
Session["albums"] = value;
}
}
答案 2 :(得分:5)
问题在于这一行:
albums = value;
您递归地将属性设置为value
,它将一次又一次地调用setter,直到它堆栈溢出。这行代码没有意义。摆脱它。
我想有一种错误的误解,即某个属性需要绑定到某个字段或其他东西。不是。一个属性本身只是几个不相关的方法,不需要彼此或字段有任何特定的关系。当您检索属性值时,只需调用其get
方法并使用返回值,并在设置其值时,使用相应的set
参数调用其value
方法。您不需要以某种方式“更改”setter中的属性值。当您更改get
将要返回的值时,将自动强制执行语义,以便下次调用get时,它将返回您已更改的Session["..."]
。
答案 3 :(得分:3)
这一行引起了你的问题,因为它最终以无限循环递归调用你的getter:
albums = value;
答案 4 :(得分:3)
经过一番快速搜索,这应该可以帮到你:Why does this cause a StackOverFlow error?
答案 5 :(得分:1)
你的setter在第一个例子中递归调用自己。你的第二个解决了这个问题。
是的,你可以做到。
答案 6 :(得分:1)
你是对的,在第一个例子中,你递归地无限次地调用专辑设置器,因此堆栈溢出。 (C#属性和方法应始终以大写字母btw开头)。
在第二个例子中,你可以简单地使用:
Session["albums"] = value;
如果你愿意的话。
答案 7 :(得分:1)
你是对的,问题是当你在引用这个setter / getter的第一个代码块中使用“albums”时。因此,当您在setter中执行albums = value
时,您将再次以递归方式调用setter。
在内部,编译器将访问器转换为函数,它可以帮助您自己查看错误:
private List<Albums> albums
{
set
{
albums = value;
Session["albums"] = albums;
}
}
编译后,变为:
private void set_albums(List<Albums> value)
{
set_albums(value);
Session["albums"] = albums;
}
答案 8 :(得分:0)
两次调用Session [“Albums”]是一个常见的错误。会话索引是一项相对昂贵的操作,涉及字典查找。
private List<Albums> Albums {
get
{
object stored = Session["albums"];
if (stored != null)
return (List<Albums>) stored;
else
{
var newValue = AlbumCollection.GetAlbums();
Albums = newValue;
return newValue;
}
}
set
{
Session["albums"] = value;
}}