.Net二进制序列化-如何限制对象图?
我有一个对象,我希望尽可能高效地在进程之间序列化和分发。对象本身引用了另一个对象,如下所示:.Net二进制序列化-如何限制对象图?,.net,serialization,.net,Serialization,我有一个对象,我希望尽可能高效地在进程之间序列化和分发。对象本身引用了另一个对象,如下所示: public class Foo { // Unique Identifier: public int Id; public Bar Bar; } public class Bar { // Unique Identifier: public int Id; } 问题是,我只想序列化Foo并在网络上运行它。我不希望在我通过线路发送的内容中包含Bar,因为它在另
public class Foo
{
// Unique Identifier:
public int Id;
public Bar Bar;
}
public class Bar
{
// Unique Identifier:
public int Id;
}
问题是,我只想序列化Foo并在网络上运行它。我不希望在我通过线路发送的内容中包含Bar,因为它在另一端是已知的,发送它会浪费我的“带宽”
我想做的是:
这是限制序列化对象图的有效方法吗?有更好的方法吗?这听起来是可行的,本质上,您可以在Foo上实现ISerializable接口,它可以让您控制如何序列化Foo
然后您实现相应的构造函数,您将有权访问保存的状态并可以提取id。这听起来是可行的,实际上您在Foo上实现了ISerializable接口,它将允许您控制如何序列化Foo
然后您实现相应的构造函数,您将有权访问保存的状态并可以提取id。您所描述的需要使用常规的
二进制格式化程序进行ISerializable
(自定义序列化)
-然而,protobuf net允许您简化事情(因此您不需要自己处理细节),同时通常会在过程中缩小数据:
[ProtoContract]
public class Foo : ISerializable
{
// Unique Identifier:
[ProtoMember(1)]
public int Id;
public Bar Bar;
[ProtoMember(2)]
private int? BarProxy {
get {
if(Bar == null) return null;
return Bar.Id;
}
set {
if(value == null) { Bar = null; }
else { // fetch from repository
Bar = new Bar();
Bar.Id = value;
}
}
}
public Foo() { }
void ISerializable.GetObjectData(SerializationInfo info,
StreamingContext context) {
Serializer.Serialize(info, this);
}
protected Foo(SerializationInfo info, StreamingContext context) {
Serializer.Merge(info, this);
}
}
public class Bar
{
// Unique Identifier:
public int Id;
}
对于更简单的设置: 您使用的是什么序列化程序
- 使用
,您可以将不需要的字段标记为BinaryFormatter
[非序列化]
- 使用
,您可以将不需要的成员标记为XmlSerializer
[XmlIgnore]
- 使用
,您只需不使用DataContractSerializer
[DataContract]
也可以考虑;这有一个非常有效的二进制机制;比<代码> BinaryFormatter < /Cult>
< P>您所描述的将要求<代码>可ISIALIALITION/<代码>(自定义序列化),使用常规<代码> BinaryFormatter < /C> >但是,TrimBuf网将允许您简化事情。(因此您不需要自己处理细节),同时通常会在过程中缩小数据:[ProtoContract]
public class Foo : ISerializable
{
// Unique Identifier:
[ProtoMember(1)]
public int Id;
public Bar Bar;
[ProtoMember(2)]
private int? BarProxy {
get {
if(Bar == null) return null;
return Bar.Id;
}
set {
if(value == null) { Bar = null; }
else { // fetch from repository
Bar = new Bar();
Bar.Id = value;
}
}
}
public Foo() { }
void ISerializable.GetObjectData(SerializationInfo info,
StreamingContext context) {
Serializer.Serialize(info, this);
}
protected Foo(SerializationInfo info, StreamingContext context) {
Serializer.Merge(info, this);
}
}
public class Bar
{
// Unique Identifier:
public int Id;
}
对于更简单的设置: 您使用的是什么序列化程序
- 使用
,您可以将不需要的字段标记为BinaryFormatter
[非序列化]
- 使用
,您可以将不需要的成员标记为XmlSerializer
[XmlIgnore]
- 使用
,您只需不使用DataContractSerializer
[DataContract]
也可以考虑;这有一个非常有效的二进制机制;比<>代码> BinaryFormatter < /Cord>
> p>我不确定我是否在这里漏掉了什么。 只需在不想序列化的字段上使用非序列化
属性即可
然后,查看如何在反序列化时修复引用
我使用类似的方法对LINQ2SQL对象进行二进制序列化
更新:
更好的主意(忘了这个)。使用,这很容易使用
使用代理方法将允许您返回该对象的另一个实例(如果已经加载到内存中的话)
更新2:
你可以在中间看到一个ISILIALIZATIORATORATH的例子。(我为前面的丑陋道歉)。 只需在不想序列化的字段上使用
非序列化
属性即可
然后,查看如何在反序列化时修复引用
我使用类似的方法对LINQ2SQL对象进行二进制序列化
更新:
更好的主意(忘了这个)。使用,这很容易使用
使用代理方法将允许您返回该对象的另一个实例(如果已经加载到内存中的话)
更新2:
中可以看到一个IsIILIALATION SURROGATH的例子。(我为前面的丑陋道歉)。
好的建议,使用非序列化。一个简短的代码示例会有帮助。什么是“序列化代理”??我认为NotSerialized是解决方案的一半-如何不序列化Bar。但还有另一半需要实现-向反序列化方指示要将哪个Bar实例注入对象。为ISerializationsProgate添加了MSDN链接。设置起来有点费时,但一旦你看到了方法,就很容易了。好的建议stion,使用非序列化。一个简短的代码示例会很有帮助。“序列化代理”是什么?我认为NotSerialized是解决方案的一半-如何不序列化Bar。但还有另一半需要实现-向反序列化方指示要将哪个Bar实例注入对象。为ISerializationsProgate添加了MSDN链接。设置起来有点费时,但一旦你看到了方法,就很容易了。呵呵,我继续我注意到你已经提到了非系列化:)呵呵,我只是注意到你已经提到了非系列化:)