我的代码在什么时候做了这个List<>变得空虚?

时间:2011-11-14 15:21:05

标签: c# list clone shallow-copy

namespace Messages
{
    public partial class Email
    {
        List<Document> attachments = new List<Document>();

        protected void Page_Load(object sender, EventArgs e)
        {
            foreach(Document document in documentList)
            {
                attachments.Add(document);
            }
        }
        protected void btnSend_Click(object sender, EventArgs e)
        {
            sendMail(attachments);
        }
    }
}

正如你猜测的那样,为了解释的目的,我已经删除了这些代码,但这几乎就是我正在做的事情。我有一种感觉,它与深度/浅层复制和克隆有关,如果是这样的话 - 有人可以帮助解释这里发生了什么以及如何避免它/以不同的方式填充列表。

非常感谢,

编辑:对不起,我写过'documentList',它实际上是:

(List<Document>)Session[Request.QueryString["documentList"]]

所以你 - 它来自一个会话变量。使用断点我可以看到附件列表正在填充,但是当它涉及到click事件处理程序时它是空的!?不为空,只计算== 0。

1 个答案:

答案 0 :(得分:2)

它变为空,因为它没有存储在ViewState中(我假设asp.net webforms来自方法名称)。

请参阅How to: Save Values in View State ASP.NET Page Life Cycle Overview

或者将值存储在会话中,请参阅How to: Save Values in Session State

EDIT2:有了额外的信息 - 我已经解决了这个问题,之前已经通过将代码从Page_load转移到辅助方法(更好)并在事件回调中使用它来解决。我原先说过事件回调是在Page_Load之前发生的 - 但是我刚刚检查了这个,但事实并非如此,但是我确信我在过去某些情况下遇到过问题,有孩子控件,Page_Load没有完成 - 可能与验证有关。

无论如何,它应该沿着以下行重新编码 - 以消除Page_load和附件之间的依赖关系。使用IENumerables(而不是列表)也可以很整洁 - 参见最后的例子。

e.g。

List<Document> getAttachments()
{
    List<Document> attachments = new List<Document>();

    foreach(Document document in (List<Document>)Session[Request.QueryString["documentList"]])
            attachments.Add(document);
}

然后在回调中:

protected void btnSend_Click(object sender, EventArgs e)
{
    sendMail(getAttachments());
}

然而也值得建议使用LINQ这样做:

IEnumerable<Document> getAttachments()
{
    return ((List<Document>)Session[Request.QueryString["documentList"]]).Select(doc => doc);
}

protected void btnSend_Click(object sender, EventArgs e)
{
    sendMail(getAttachments());
    // or if sendMail doesn't accept IEnumerable then do :
    //sendMail(getAttachments().ToList());
}