您指的是“将字段标记为不可序列化”,所以我假设您正在使用BinaryFormatter
and [NonSerialized]
。如果是这样,唯一的办法就是有条件的序列化是通过实现ISerializable
并添加一个类似的构造函数,并将逻辑放在GetObjectData
执行。但这是乏味且容易出错的。我建议查看 protobuf-net,它具有更简单的条件序列化,使用使用的标准模式TypeDescriptor
and XmlSerializer
,但仍然是二进制输出(比BinaryFormatter
, 实际上)。具体来说:
[ProtoContract]
public class SomeType {
[ProtoMember(1)]
public string Name {get;set;}
private bool ShouldSerializeName() {
// return true to serialize Name, false otherwise
}
}
This ShouldSerialize*
是一个标准的基于名称的约定 - 没有特定于此序列化器的内容。
这是相同的通过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-net,您可以根据具体情况进行处理。
实际上,您也可以混合搭配,即如果您坚持使用BinaryFormatter
,您仍然可以将工作卸载到 protobuf-net,但是它会改变格式(所以不会与旧数据兼容)。例如:
[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);
}
}