简短的问题:当我将一个对象的同一个实例放入视图状态两次时,在反序列化时有两个实例。我希望只有一个实例。这可以做到吗?怎么做?
啰嗦的解释:
考虑以下代码:
public partial class MyControl : System.Web.UI.UserControl
{
[Serializable]
class MyClass
{
public string x;
}
public void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack)
{
MyClass a = (MyClass)this.ViewState["a"];
MyClass b = (MyClass)this.ViewState["b"];
MessageManager.Show((a == b).ToString(), MessageSeverity.Debug);
}
else
{
var x = new MyClass() { x = "stackoverflow" };
this.ViewState["a"] = x;
this.ViewState["b"] = x;
MessageManager.Show("Init", MessageSeverity.Debug);
}
}
}
当它运行并启动回发时,我收到消息“false”。也就是说,虽然我在视图状态中放置了一个对象,但它被序列化了两次。这可以通过检查视图状态内容来验证。
如果我尝试将交叉引用对象放在视图状态中,那么每个项目都会被序列化为单独的图形。为了显示:
public partial class MyControl : System.Web.UI.UserControl
{
[Serializable]
class MyClass
{
public string x;
public MyClass other;
}
public void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack)
{
MyClass a = (MyClass)this.ViewState["a"];
MyClass b = (MyClass)this.ViewState["b"];
MessageManager.Show((a.other == b).ToString(), MessageSeverity.Debug);
MessageManager.Show((a.other.other == a).ToString(), MessageSeverity.Debug);
}
else
{
var a = new MyClass() { x = "stack" };
var b = new MyClass() { x = "overflow" };
a.other = b;
b.other = a;
this.ViewState["a"] = a;
this.ViewState["b"] = b;
MessageManager.Show("Init", MessageSeverity.Debug);
}
}
}
现在我收到消息“False”和“True”(按此顺序)。同样,检查 Viewstate 显示,每个对象都被序列化了两次。是什么赋予了?我检查了System.Web.UI.StateBag
ILSpy 的来源,但它只是将所有值推入一个ArrayList
,并且也没有特殊的序列化代码。因此,无论是谁序列化视图状态(System.Web.UI.ObjectStateFormatter
?),都会以某种方式将每个对象序列化为一个单独的图......为什么?我可以解决它吗?
更新:我需要这个的原因是同一个对象将由两个单独的组件持久化,并且在反序列化时我想检查它们是否具有相同的对象。(或者更确切地说,它们本身都存储对象集合,我需要同步这些集合)。
我可以用十几种不同的方式实现自定义比较,但是由于我想对任意对象执行此操作,所以有点棘手。;)