- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写自己的 IFormatter 实现,但我想不出一种方法来解决两种都实现 ISerializable 的类型之间的循环引用。
这是通常的模式:
[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);
}
}
然后我这样做:
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);
如果我使用开箱即用的 BinaryFormatter 对 b 进行序列化和反序列化,则上述引用相等性测试会像预期的那样返回 true。但是我想不出在我的自定义 IFormatter 中实现此目的的方法。
在非 ISerializable 情况下,一旦目标引用已被解析,我可以简单地使用反射重新访问“待定”对象字段。但是对于实现 ISerializable 的对象,不可能使用 SerializationInfo 注入(inject)新数据。
谁能指出我正确的方向?
最佳答案
这种情况是FormatterServices.GetUninitializedObject
的原因方法。一般的想法是,如果你有对象 A 和 B,它们在它们的 SerializationInfo
中相互引用,你可以按如下方式反序列化它们:
(出于此解释的目的,(SI,SC)
指的是类型的反序列化构造函数,即采用 SerializationInfo
和 StreamingContext 的构造函数
。)
GetUninitializedObject
以分配(但不初始化)A 类型的实例,因为您还没有准备好调用它的 (SI,SC)
构造函数。SerializationInfo
对象(它将包括对现在反序列化一半的 A 的引用)并将其传递给 B 的 (SI,SC)
构造函数。SerializationInfo
对象并调用 A 的 (SI,SC)
构造函数。您可以通过反射在现有实例上调用构造函数。GetUninitializedObject
方法是纯粹的 CLR 魔术 - 它创建一个实例而无需调用构造函数来初始化该实例。它基本上将所有字段设置为零/空。
这就是警告您不要在 (SI,SC)
构造函数中使用子对象的任何成员的原因 - 子对象可能已分配但此时尚未初始化.这也是 IDeserializationCallback
接口(interface)的原因,它使您有机会在保证完成所有对象初始化之后和返回反序列化对象图之前使用您的子对象。
ObjectManager class 可以为您完成所有这些(以及其他类型的修复)。但是,考虑到反序列化的复杂性,我总是发现它的文档很少,所以我从来没有花时间去尝试弄清楚如何正确使用它。它使用一些更神奇的方法来执行第 4 步,使用一些经过优化的内部到 CLR 反射来更快地调用 (SI,SC)
构造函数(我已经将它计时的速度大约是公共(public)方式)。
最后,有些对象图涉及无法反序列化的循环。一个例子是当你有一个由两个 IObjectReference
实例组成的循环时(我已经测试了 BinaryFormatter
并且它抛出了一个异常)。另一个我怀疑是如果你有 cycle involving nothing but boxed value-types .
关于.net - 解决实现 ISerializable 的对象的循环引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2712393/
我目前正在努力保存更大的对象结构,其中包含我正在处理的应用程序中的“项目”所需的所有数据。数据是诸如图片、流文档以及更基本的数据类型之类的东西。 现在,我目前的方法是在我需要保存的对象中包含的所有类上
我有一个类,其中包含我正在序列化的一些数据: [Serializable] public class SomeData { public int NumericField; publi
我必须使用一个旧应用程序,该应用程序使用 binaryFormatter 将应用程序数据序列化为文件流(例如在名为“data.oldformat”的文件中) 没有任何优化,主类已用属性标记 publi
考虑以下类的 POD 类型: public class Price { public decimal OfferPrice { get; set; } } 此类的对象是从服务器检索的,所以让我们用可序
我打算使用序列化来做克隆。我必须让我的类 ISerializable。但是它的父类(super class)和所有引用的变量类呢?我需要让它们全部 ISerializable 吗? 如果我使用 ISe
ISerializable 接口(interface)只提供了一种序列化对象的方法。反序列化进程由构造函数管理。 问题是,构造函数不能返回实例,因为构造函数创建了一个新实例。 在我的实现中,有几个属性
我们的任务非常简单,我们有一个对象图,其中每个对象 (IDItem) 都有一个唯一的 ID。对象图存在两次,在客户端和服务器机器上。 现在我们将一些可序列化的命令传递给服务器。该命令具有一些 IDIt
我正在编写自己的 IFormatter 实现,但我想不出一种方法来解决两种都实现 ISerializable 的类型之间的循环引用。 这是通常的模式: [Serializable] class Foo
我们有一个遗留类A,它是[Serializable],但不是ISerializable。由于各种原因,必须修补此类以实现 ISerializable。 问题是我们仍然需要能够加载旧的保存文件,这些文件
我想为包含相似类型子项列表的 C# 类实现 ISerializable。考虑以下示例: using System; using System.Collections.Generic; using Sy
我很难理解 ISerializable 接口(interface)的必要性......我想我在这个主题中遗漏了一些非常重要的东西,所以如果有人能帮助我,我将不胜感激。 这很好用- [Serializa
我有扩展方法 public static T DeepClone(this T source) where T : ISerializable { .. } 当我添加“where T : I
我正在尝试使用 Iserializable 在 Android 中传递对象,但它返回“无法从 native 句柄激活类型的实例”异常。 下面是我的代码。 [FBUserParcel.cs] using
我正在编写自定义序列化程序,我刚刚完成了用于处理 ISerializable.GetObjectData 的部分的实现。但是当我去反序列化信息并将其重新应用于图形时,我没有看到 Set-ObjectD
我正在阅读 msdn 上的自定义序列化文章:http://msdn.microsoft.com/en-us/library/ty01x675%28VS.80%29.aspx 里面提到了实现自定义序列化
我必须在派生类中实现 ISerializable(以执行一些自定义序列化/反序列化),但父类被标记为 [Serializable]。序列化“有效”(我可以序列化和反序列化而不会出现运行时错误)但看起来
我有一组用户定义的类型,它们已经实现了 ISerializable 接口(interface),现在我想将它们托管在服务器端应用程序中,并通过使用 DataContract 属性标记它们来向客户端公开
我有一个看起来像这样的包装列表: [JsonObject(MemberSerialization.Fields)] public class OrderManager : IEnumerable, I
我对继承类中 ISerializable 的正确实现有疑问。 我有两个类,AbstractBaseClass 及其实现 BaseClass。在实现派生自 BaseClass 的 FinalClass
我有一个类通过 XLINQ 实现它自己的(反)序列化,我会喜欢让我类(class)的客户尝试对我的类(class)进行 XMLSerialze而是调用了我的 XLINQ 方法。 这可能吗? 最佳答案
我是一名优秀的程序员,十分优秀!