J'écris ma propre implémentation IFormatter et je ne peux pas trouver de moyen de résoudre les références circulaires entre deux types qui implémentent ISerializable.Résolution de références circulaires pour les objets implémentant ISerializable
Voici le schéma habituel:
[Serializable]
class Foo : ISerializable
{
private Bar m_bar;
public Foo(Bar bar)
{
m_bar = bar;
m_bar.Foo = this;
}
public Bar Bar
{
get { return m_bar; }
}
protected Foo(SerializationInfo info, StreamingContext context)
{
m_bar = (Bar)info.GetValue("1", typeof(Bar));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("1", m_bar);
}
}
[Serializable]
class Bar : ISerializable
{
private Foo m_foo;
public Foo Foo
{
get { return m_foo; }
set { m_foo = value; }
}
public Bar()
{ }
protected Bar(SerializationInfo info, StreamingContext context)
{
m_foo = (Foo)info.GetValue("1", typeof(Foo));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("1", m_foo);
}
}
-je alors ceci:
Bar b = new Bar();
Foo f = new Foo(b);
bool equal = ReferenceEquals(b, b.Foo.Bar); // true
// Serialise and deserialise b
equal = ReferenceEquals(b, b.Foo.Bar);
Si j'utilise un hors-the-box BinaryFormatter à serialise et deserialise b, le test ci-dessus pour reference-equality renvoie true comme on pourrait s'y attendre. Mais je ne peux pas concevoir un moyen d'y parvenir dans mon IFormatter personnalisé.
Dans une situation non-ISerializable je peux simplement revoir les champs d'objet "en attente" en utilisant la réflexion une fois que les références cibles ont été résolues. Mais pour les objets implémentant ISerializable, il n'est pas possible d'injecter de nouvelles données en utilisant SerializationInfo.
Quelqu'un peut-il me diriger dans la bonne direction?
Je comprends votre point de vue sur les "tags de référence" et mon formateur utilise déjà cette technique. Ainsi, votre exemple d'autoréférence n'est pas un problème pour moi. Mais je ne vois pas comment votre réponse m'aide avec les objets implémentant ISerializable qui se réfèrent mutuellement. Êtes-vous capable de résoudre ce problème spécifique? Merci. – Chris
Pas tout à fait sûr de ce que vous voulez dire. Parlez-vous d'utiliser le constructeur privé lié à la sérialisation? –
Oui, exactement. La seule façon de gonfler un objet qui implémente ISerializable est d'appeler son constructeur spécial. – Chris