Краткий вопрос: когда я дважды помещаю один и тот же экземпляр объекта в состояние просмотра, после десериализации получается два экземпляра. Я хочу, чтобы был только один экземпляр. Можно ли это сделать и как?
Многословное объяснение:
Рассмотрим следующий код:
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);
}
}
}
Теперь я получаю сообщения «Ложь» и «Верно» (именно в таком порядке). Опять же, проверка Viewstate показывает, что каждый объект сериализовался дважды. Что дает? Я проверил источник System.Web.UI.StateBag
с помощью ILSpy, но он просто помещает все значения в ArrayList
, и в нем также нет специального кода сериализации. Итак, кто бы ни сериализовал состояние просмотра (System.Web.UI.ObjectStateFormatter
?), Каким-то образом берет каждый объект и сериализует его как отдельный граф ... почему ??? И я могу обойти это?
Обновление. Причина, по которой мне это нужно, заключается в том, что один и тот же объект будет сохраняться двумя отдельными компонентами, и после десериализации я хотел бы проверить, есть ли у них один и тот же объект. (Вернее, они оба хранят коллекции самих объектов, и мне нужно синхронизировать эти коллекции).
Я мог бы реализовать собственное сравнение десятком разных способов, но, поскольку я хочу сделать это для произвольных объектов, это становится довольно сложно. ;)