Игнорировать свойство во время сериализации с использованием BinaryFormatter, только если его значение равно NULL - PullRequest
0 голосов
/ 10 апреля 2020

В настоящее время я использую BinaryFormatter для создания потока. Мне известно о том, что я могу пометить свойство с атрибутом [field: NonSerialized], если хочу, чтобы оно игнорировалось BinaryFormatter во время сериализации. У меня вопрос, есть ли способ указать мне, что все нулевые свойства поля должны игнорироваться во время двоичной сериализации? В настоящее время я делаю что-то вроде этого, чтобы получить поток

       var formatter = new BinaryFormatter();
        using (var stream = new MemoryStream())
        {
            formatter.Serialize(stream, MyObjectinstance);
        }

Ответы [ 2 ]

0 голосов
/ 11 апреля 2020

Не предназначен для этой конкретной цели, но ISerializationSurrogate может помочь.

Я отредактирую и дополню свой ответ позже, но следующее выполняет то, что вам нужно, но не может достичь того же для вложенного objects.

Параметр obj здесь является экземпляром вашего класса. Мы просто опускаем добавление поля в информацию сериализации, если его значение равно нулю:

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, SerializationInfo info, 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;
}

Надеюсь, это помогает. Я все еще работаю над вложенными полями типов классов.

0 голосов
/ 11 апреля 2020

Каков ваш конкретный вариант использования исключения из сериализации? Null практически не займет места, и это не улучшит производительность десериализации или сериализации. При десериализации вы также можете обрабатывать ноль по-другому, обрабатывая событие OnDeserialized.

...