Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么这会导致堆栈溢出错误?_C#_.net - Fatal编程技术网

C# 为什么这会导致堆栈溢出错误?

C# 为什么这会导致堆栈溢出错误?,c#,.net,C#,.net,这会导致StackOverFlow错误,我知道原因,但我想了解更多关于原因的详细信息,以及我的解决方案是如何处理的。好的,首先,当我尝试为属性赋值时,以下代码会导致StackOverFlow错误: private List<Albums> albums { get { if (Session["albums"] != null) return (List<Albums>)Session["albums"];

这会导致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,分配了值,然后为会话[albums]分配了albums中的值?我是否可以改为Session[albums]=value?

您正在重新分配给属性本身

在您的情况下,您只使用会话

所以这应该没问题

private List<Albums> albums
{
    get
    {
        if (Session["albums"] == null)
            Session["albums"] = AlbumCollection.GetAlbums();
        return (List<Albums>)Session["albums"];
    }
    set
    {
        Session["albums"] = value;
    }
}

这一行的问题在于:

albums = value;
您正在递归地将属性设置为值,该值将一次又一次地调用setter,直到它溢出。那行代码没有意义。把它扔掉


我猜有一种错误的误解,认为属性需要绑定到字段或其他内容。不是。属性本身只是两个不相关的方法,它们之间或字段之间不需要有任何特定的关系。在检索属性值时,只需调用其get方法并使用返回值,在设置其值时,使用适当的value参数调用其set方法。您不需要以某种方式更改setter中的属性值。当您更改get将返回的值时,语义将自动强制执行,因此下次调用get时,它将返回您已经更改的会话[…]

在第一个示例中,setter递归地调用自己。你的第二个解决了这个问题


是的,你本可以这样做的。

因为在你的setter中,你正在呼叫。。。setter,它指向setter,并调用。。。二传手。。。而且

 set
 {    
    albums = value;       // < --- This line calls itself again.. 
    Session["albums"] = 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属性的更多信息,请查看。

这一行导致了您的问题,因为它会在无限循环中递归调用getter:

albums = value;

您是正确的,在第一个示例中,您递归调用唱片集设置器无限次,因此堆栈溢出。C属性和方法应始终以大写字母btw开头

在第二个示例中,您可以简单地使用:

Session["albums"] = value;

如果您愿意。

您是正确的,问题是当您在第一个代码块中使用相册时,您指的是这个setter/getter。因此,当您在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;
}

给Session[相册]打两次电话是一个常见的错误。会话索引是一项涉及字典查找的相对昂贵的操作

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;
}}

所以,如果我有Session[albums]=value,就可以了?@Xaisoft:是的,这就是你所需要的一切。@Xaisoft:这是一种方法;但是,如果在页面处理过程中多次访问Albums属性,则最好将反序列化结果缓存到私有成员中。好的,有点困惑,我应该执行Session[Albums]=value还是Session[Albums]=Albums,还是相同的操作。@Chris,你指的是我在第二次尝试中声明私有变量albums的实际方式吗?这也带来了另一个问题,创建另一个变量如何缓存结果?我不清楚这一点?好吧,我想我可以做到,但我担心如果我不先做albums=value,我会做错。谢谢。我明白你的意思了,不是在if语句中访问会话,而是在我返回相册列表时,先将其存储在对象中,然后检查对象?对吗?在快速搜索之后,这应该可以帮助您: