我有一个班级,有几个成员,我想序列化以存储州。
但是,我想从WITHIN本身序列化,而不是通过一些外部类将其提供给格式化程序。
所以理论上我想做的事情是:
[DataContract]
class MyClass
{
[DataMember]
private MyCompoundClass _someCompoundField;
[DataMember]
private int _someOtherField;
private void SaveState()
{
using (Stream stream = GetStream())
{
DataContractSerializer serialiser = new DataContractSerializer(typeof(MyClass));
serialiser.WriteObject(stream, this);
}
}
private void LoadState()
{
using (Stream stream = GetStream())
{
DataContractSerializer serialiser = new DataContractSerializer(typeof(MyClass));
this = (MyClass)serialiser.ReadObject(stream);
}
}
}
现在显然是
行 this = (MyClass)serialiser.ReadObject(stream);
是胡说八道,但你可以看到我正在尝试做什么。我想从类中序列化我的类的两个字段。 (我正在使用WCF序列化程序,但我认为如果我使用XmlSerializer,这将是相同的。)
我尝试通过自己序列化每个字段来正确实现这一点:
private void SaveState()
{
using (Stream stream = GetStream())
{
//serialise field 1
DataContractSerializer serialiser = new DataContractSerializer(typeof(MyCompoundClass));
serialiser.WriteObject(stream, _someCompoundField);
//serialise field 2
serialiser = new DataContractSerializer(typeof(int));
serialiser.WriteObject(stream, _someOtherField);
}
}
现在这可以作为一个保存,但是当我来回读取文档时,由于XML文件中有两个根节点,因此抛出异常。
如何创建我的“包装器”节点来包装我的字段。或者还有其他方法我应该这样做吗?
非常感谢,
答案 0 :(得分:1)
我还没有看到任何修改现有对象的内置反序列化方法,而不是返回一个新对象。我看到你的选择是:
MyClass
并将成员复制到LoadState
设为静态,并让其返回反序列化的MyClass
答案 1 :(得分:1)
你可以在你的LoadState上执行:
private void LoadState()
{
using (Stream stream = GetStream())
{
DataContractSerializer serialiser = new DataContractSerializer(typeof(MyClass));
MyClass deserialized = (MyClass)serialiser.ReadObject(stream);
this._someCompoundField = deserialized._someCompoundField;
this._someOtherField = deserialized._someOtherField;
}
}
答案 2 :(得分:0)
您是否与特定的序列化程序绑定? protobuf-net支持该用例,例如:
[DataContract]
class MyClass
{
[DataMember(Order = 1)]
private MyCompoundClass _someCompoundField;
[DataMember(Order = 2)]
private int _someOtherField;
private void SaveState()
{
using (Stream stream = GetStream())
{
ProtoBuf.Serializer.Serialize(stream, this);
}
}
private void LoadState()
{
using (Stream stream = GetStream())
{
ProtoBuf.Serializer.Merge(stream, this);
}
}
}
注意在member-attributes上添加Order = n
;这是因为protobuf在字段/属性上使用数字标识符,并且需要一种方法来选择它们。您还可以使用项目特定的[ProtoContract]
/ [ProtoMember(n)]
属性,但它也适用于WCF(如图所示)。
(Merge
也适用于非通用2.0 API - 但您将this
作为参数传递给Deseroalize
而不是
答案 3 :(得分:0)
将反序列化方法放在静态方法中:
class MyClass
{
public static MyClass LoadState()
{
// Deserialize, and return the new MyClass instance.
}
}
要序列化一些对象,注释一些字段以避免序列化,或者仅使用要序列化的字段创建超类或接口。