.NET序列化:如何选择性地忽略数据字段 [英] .net serialization: how to selectively ignore data fields
问题描述
在。网你可以标记一个字段作为非序列化,并且化期间,将跳过。
In. Net you can mark a field as non serializable, and it will be skipped during serialization.
我在找一个简单的方法,让我在运行时控制特定字段是否应序列。
I'm looking for a simple method that will allow me to control in runtime whether a specific field should be serialized.
推荐答案
您指的是标记字段作为非序列化,所以我假设你正在使用的BinaryFormatter
和 [非序列化]
。如果是这样,只有这样才能做到的条件的序列化是通过实施 ISerializable的
并添加了类似的构造函数,并把逻辑在 GetObjectData使用
的实施。这是繁琐且容易出错,虽然。我建议在看protobuf网,里面有简单的条件系列化,使用由 TypeDescriptor
标准模式和的XmlSerializer
,但仍然是二进制输出(比的BinaryFormatter
更有效,实际上)。具体做法是:
You are referring to "mark a field as non serializable", so I assume you are using BinaryFormatter
and [NonSerialized]
. If so, the only way to do conditional serialization is by implementing ISerializable
and adding a similar constructor, and putting the logic in the GetObjectData
implementation. This is tedious and error prone, though. I would suggest looking at protobuf-net, which has simpler conditional serialization, using the standard patterns used by TypeDescriptor
and XmlSerializer
, but is still binary output (more efficient than BinaryFormatter
, actually). Specifically:
[ProtoContract]
public class SomeType {
[ProtoMember(1)]
public string Name {get;set;}
private bool ShouldSerializeName() {
// return true to serialize Name, false otherwise
}
}
本 ShouldSerialize *
是一个标准的基于名称的约定 - 没有什么特定于该串行
This ShouldSerialize*
is a standard name-based convention - nothing specific to this serializer.
下面是通过相同的 ISerializable的
:
[Serializable]
public class SomeType : ISerializable
{
public SomeType() { }
public string Name { get; set; }
void ISerializable.GetObjectData(
SerializationInfo info, StreamingContext context)
{
if (/* should serialize Name */) info.AddValue("Name", Name);
//... all other fields
}
protected SomeType(SerializationInfo info, StreamingContext context)
{
foreach (SerializationEntry entry in info)
{
switch (entry.Name)
{
case "Name": Name = (string)entry.Value; break;
//... all other fields
}
}
}
}
很多更多的维护;特别是,你必须在使用 ISerializable的
来承担所有成员的责任 - 不过,如果你只是使用protobuf网,你可以处理每一个案件逐案的基础。
Lots more to maintain; in particular, you have to take responsibility for all members when using ISerializable
- however, if you just use protobuf-net you can handle each on a case-by-case basis.
其实,你可以混合和匹配也是如此,也就是说,如果你被卡住使用的BinaryFormatter
,你仍然可以卸载工作,protobuf网,但<强>它会改变格式(所以不会与旧的数据兼容)。例如:
Actually, you can mix-and-match too, i.e. if you are stuck with using BinaryFormatter
, you can still offload the work to protobuf-net, but it will change the format (so won't be compatible with old data). For example:
[Serializable, ProtoContract]
public class SomeType : ISerializable
{
public SomeType() { }
[ProtoMember(1)]
public string Name { get; set; }
private bool ShouldSerializeName() { /* condition */ }
void ISerializable.GetObjectData(
SerializationInfo info, StreamingContext context)
{
Serializer.Serialize(info, this);
}
protected SomeType(SerializationInfo info, StreamingContext context)
{
Serializer.Merge(info, this);
}
}
这篇关于.NET序列化:如何选择性地忽略数据字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!