gpt4 book ai didi

c# - 有没有办法在 View 状态中存储匿名委托(delegate)?

转载 作者:太空狗 更新时间:2023-10-29 21:45:55 25 4
gpt4 key购买 nike

WebControl 中,我有一个属性 Filters 定义如下:

public Dictionary<string, Func<T, bool>> Filters
{
get
{
Dictionary<string, Func<T, bool>> filters =
(Dictionary<string, Func<T, bool>>)ViewState["filters"];
if (filters == null)
{
filters = new Dictionary<string, Func<T, bool>>();
ViewState["filters"] = filters;
}
return filters;
}
}

这个 webcontrol 是一个 DataSource,我创建这个属性是因为我想有可能轻松地过滤数据,例如:

//in page load    
DataSource.Filters.Add("userid", u => u.UserID == 8);

但是,如果我将代码更改为:

//in page load    
int userId = int.Parse(DdlUsers.SelectedValue);
DataSource.Filters.Add("userid", u => u.UserID == userId);

它不再工作了,我得到这个错误:

Type System.Web.UI.Page in Assembly '...' is not marked as serializable.

发生了什么:

  1. 序列化程序检查字典。它看到它包含一个匿名委托(delegate)(此处为 lambda)
  2. 由于委托(delegate)是在一个类中定义的,它会尝试序列化整个类,在本例中为 System.Web.UI.Page
  3. 此类未标记为可序列化
  4. 它抛出异常是因为 3.

有什么方便的解决方案来解决这个问题吗?出于显而易见的原因,我无法将所有使用数据源的网页标记为[可序列化]。


EDIT 1 :我不明白的东西。如果我将 Dictionary 存储在 Session 对象中(它使用 BinaryFormatterLosFormatter 用于 ViewState),它有效!我不知道这怎么可能。也许 BinaryFormatter 可以序列化任何类,甚至那些不是 [serializable] 的类?


EDIT 2:重现问题的最小代码:

void test()
{
Test test = new Test();
string param1 = "parametertopass";
test.MyEvent += () => Console.WriteLine(param1);

using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, test); //bang
}
}

[Serializable]
public class Test
{
public event Action MyEvent;
}

最佳答案

好问题。我可以确认您的诊断(稍作更正:基础架构尝试序列化可能包含对您页面的引用的闭包类)。

您可以定义自己的闭包类并将其序列化:

[Serializable] class Closure { int userId; bool Filter(User u) { ... } };

不过,这并不方便。

我建议您使用不同的模式:不要序列化“代码”。序列化过滤器使用的数据:

class FilterSettings { int userId; int someOtherFiler; string sortOrder; ... }

虽然我无法指出我更喜欢的确切原因,但我凭直觉知道这是一种更好的方法。

关于c# - 有没有办法在 View 状态中存储匿名委托(delegate)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12158449/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com