ISerialized接口仅提供序列化对象的方法。反序列化过程由构造函数管理。
问题是,该构造函数无法返回实例,因为构造函数创建了一个新实例。
在我的实现中,有几个与在其他地方实例化和维护的单例相对应的属性。
我需要反序列化过程来获取该实例并分配给该属性,而不是创建一个新实例。
构造函数方法不适合这种情况。
在 Java 中,您将调用 ReadResolve() 方法,C# 中是否有等效的方法?
我们的任务非常简单,我们有一个对象图,其中每个对象(IDItem)都有一个唯一的ID.对象图在客户端和服务器计算机上存在两次.
现在我们将一些可序列化的命令传递给服务器.该命令具有一些IDItem作为字段.IDItems实现ISerializable接口,只将它们的ID存储在SerializationInfo中.喜欢:
// The method called when serializing a IDItem.
void GetObjectData(SerializationInfo info, StreamingContext context)
{
// Instead of serializing this object, just save the ID
info.AddValue("ID", this.GetID());
}
Run Code Online (Sandbox Code Playgroud)
问题是,我们如何将现有对象分配给反序列化器创建的实例?显然,ISerializable构造函数中的以下内容不起作用,因为'this'标识符是只读的:
//does not work
protected IDItem(SerializationInfo info, StreamingContext context)
{
this = GlobalObject.GetIDItem(info.GetString("ID"));
}
Run Code Online (Sandbox Code Playgroud)
那么任何想法我们如何将现有对象分配给反序列化对象?
最诚挚的问候,thalm
我正在编写自己的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 …Run Code Online (Sandbox Code Playgroud) 我翻译我的项目使用protobuf-net而不是BinaryFormatter.它看起来像有一个缺少文档http://code.google.com/p/protobuf-net/w/list 我也查阅了一些例子,从http://code.google.com/p/protobuf-net/source/browse / 但有些事情对我来说仍然不明确,这就是我决定在这里问的原因:
1.关于ISerializable和Serializer.Merge/Serialize
如果我们从ISerializable继承以进行特定的序列化.正如我读到的:ProtoBuf-Net ProtoInclude Generic Type Subclass 我们必须使用一个钩子Serializer.Merge/Serialize;
假设我们有课:
[Serializable]
[ProtoContract]
public class Anchor : ISerializable
{
[ProtoMember(1)]
public int id;
[ProtoMember(2)]
public Ship ship;
...
}
Run Code Online (Sandbox Code Playgroud)
在 Serializer.Merge(信息,这一点); 必须添加到构造函数Anchor(SerializationInfo info,StreamingContext context)
和 Serializer.Serialize(info,this); 添加到void GetObjectData(SerializationInfo info,StreamingContext context)
所以,我们有:
protected Anchor(SerializationInfo info, StreamingContext context)
{
//for binaryformatter:
Type myType = typeof(Anchor);
foreach (SerializationEntry e in info)
{
FieldInfo f = myType.GetField(e.Name,BindingFlags.NonPublic|BindingFlags.Public|BindingFlags.Public|BindingFlags.Instance);
f.SetValue(this,e.Value);
}
//added for protobuf-net:
Serializer.Merge(info, this);
}
public virtual void …Run Code Online (Sandbox Code Playgroud) inheritance serialization protocol-buffers protobuf-net iserializable
虽然有一个名为的接口ISerializable,但似乎是为了在类型被标记为[Serializable]属性时自定义详细信息.如果我理解正确,[Serializable]属性本身不会触及它附加的类型上的任何内容,但在运行时实现的事情IFormatter确定给定对象是否标记[Serializble]属性(通过反射?我猜).IFormatter.Serializble()方法也只需要任何方法Object.这是否意味着几乎.NET中的每个对象都可以序列化?如果没有,是否有方法只接受可序列化的对象并在传递非序列化对象时产生编译时错误?