Подтвердить что ты не робот

Почему у SerializationInfo нет методов TryGetValue?

При реализации интерфейса ISerializable в С# мы предоставляем конструктор, который принимает объект SerializationInfo, а затем запрашивает его с помощью различных методов GetInt32, GetObject и т.д., чтобы заполнить поля объекта которые мы пытаемся десериализовать.

Одна из основных причин реализации этого интерфейса, а не просто использование атрибута [Serializable], заключается в обратной совместимости: если в какой-то момент мы добавили новые классы в класс, мы сможем поймать SerializationException, созданный сериализованным, более старую версию класса и обрабатывать их соответствующим образом.

Мой вопрос заключается в следующем: почему мы должны использовать эти исключения для того, что, по сути, управляет потоком? Если я десериализую большое количество классов, которые были сохранены некоторое время назад, потенциально каждое отсутствующее поле в каждом классе генерирует исключение, что вызывает очень плохую производительность.

Почему класс SerializationInfo не предоставляет методы TryGetValue, которые просто возвращают false, если строка имени не присутствовала?

4b9b3361

Ответ 1

Вы можете перебирать доступные поля и использовать switch, хотя...

            foreach(SerializationEntry entry in info) {
                switch(entry.Name) {
                    ...
                }
            }

Или вы можете использовать protobuf-net;-p

Ответ 2

Ну, никто не ответил "почему", но я предполагаю, что это адресовано MS.

Моя реализация для любого, кто в ней нуждается:

public static class SerializationInfoExtensions
{
    public static bool TryGetValue<T>(this SerializationInfo serializationInfo, string name, out T value)
    {
        try
        {
            value = (T) serializationInfo.GetValue(name, typeof(T));
            return true;
        }
        catch (SerializationException)
        {
            value = default(T);
            return false;
        }
    }

    public static T GetValueOrDefault<T>(this SerializationInfo serializationInfo, string name, Lazy<T> defaultValue)
    {
        try
        {
            return (T) serializationInfo.GetValue(name, typeof(T));
        }
        catch (SerializationException)
        {
            return defaultValue.Value;
        }
    }
}