仅当使用null时,才使用BinaryFormatter忽略属性

我当前正在使用BinaryFormatter创建流。我知道一个事实,如果我希望在序列化期间BinaryFormatter忽略该属性,则可以使用属性[field: NonSerialized]标记该属性。我的问题是,是否有一种方法可以指定在二进制序列化期间应忽略字段的所有空属性?我目前正在做这样的事情来获取信息流

       var formatter = new BinaryFormatter();
        using (var stream = new MemoryStream())
        {
            formatter.Serialize(stream,myobjectinstance);
        }
qq090630 回答:仅当使用null时,才使用BinaryFormatter忽略属性

您将序列化排除在特定情况下的用例是什么? Null几乎不会占用任何空间,并且不会提高反序列化或序列化性能。反序列化时,还可以通过处理OnDeserialized事件来以不同方式处理null。

,

并非专门用于此目的,但是ISerializationSurrogate可以提供帮助。

稍后我将编辑并丰富我的答案,但是以下内容可以满足您的需要,但对于嵌套对象却无法实现。

这里的obj参数是您的类的实例。如果该字段的值为null,我们只是忽略将一个字段添加到序列化信息中:

public class NullFieldOmittingSurrogate : ISerializationSurrogate
{
    void ISerializationSurrogate.GetObjectData(object obj,SerializationInfo info,StreamingContext context)
    {
        if (obj != null)
        {
            foreach (FieldInfo field in obj.GetType().GetFields
                (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                object fieldValue = field.GetValue(obj);
                if (fieldValue != null)
                {
                    info.AddValue(field.Name,fieldValue);
                }
            }
        }
    }

    object ISerializationSurrogate.SetObjectData(object obj,StreamingContext context,ISurrogateSelector selector)
    {
        // The deserialization works without the need for this surrogate
        throw new NotImplementedException();
    }
}

我们需要将此替代项传递给我们的二进制格式化程序,因此这是一种将其以及其他必需信息传递给它的方法:

public static void SerializeObject(object myObjectInstance,Stream destinationStream)
{
    SurrogateSelector surrogateSelector = new SurrogateSelector();
    surrogateSelector.AddSurrogate
    (
        myObjectInstance.GetType(),new StreamingContext(StreamingContextStates.All),new NullFieldOmittingSurrogate()
    );
    IFormatter serializer = new BinaryFormatter();
    serializer.SurrogateSelector = surrogateSelector;
    serializer.Serialize(destinationStream,myObjectInstance);
}

最后,如何使用:(SerClass是无关紧要的,是具有4个object类型的属性的类,用于单元测试)

public static void Main()
{
    MemoryStream memoryStream = new MemoryStream();
    SerializeObject
    (
        new SerClass()
        {
            Prop2 = 5,Prop4 = "ABCD",Nested = new SerClassNested() { Prop1 = 8,Prop3 = "EFGH" }
        },memoryStream
    );

    SerClass serClass = new BinaryFormatter().Deserialize(memoryStream) as SerClass;
}

希望这会有所帮助。我仍在处理嵌套的类类型字段。

本文链接:https://www.f2er.com/2467520.html

大家都在问