ISerializable производительность десериализации

При реализации ISerializable вы пишете такой код для выполнения пользовательской десериализации...

(Примечание: это тривиальный пример и не требует специальной десериализации).

protected ClientInformation(SerializationInfo info, StreamingContext context)
{
    _culture = (string)info.GetValue("Culture", typeof(string))
}

Методу GetValue требуется тип, который вы хотите десериализовать, который согласно справке intellisense делает следующее

"Если сохраненное значение не может быть преобразовано в этот тип, система выдаст исключение System.InvalidCast"

Означает ли это, что в моем примере утверждения выполняется два приведения?

Кроме того, какой смысл добавлять этот параметр типа, потому что если я напишу следующее

_culture = info.GetValue("Culture", typeof(string))

... это все равно не скомпилируется, так как вы "не можете неявно преобразовать тип" объект "в" строку "". Таким образом, это означает, что я должен в любом случае привести объект к действию, и поэтому, если приведение будет недействительным, я получу исключение InvalidCastException через собственное приведение в любом случае.

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

Обновление: Может быть, за кадром используется оператор "is", чтобы проверить тип, что ожидается? "Is" автоматически пытается разыграть?

1 ответ

Если мы посмотрим на реализацию GetValue, то кажется, что сам объект не приводится, но происходит хотя бы одно приведение (Type to RuntimeType).

И еще несколько проверок, которые считают, что ваш объект был брошен менее важным, насколько я могу судить.

public object GetValue(string name, Type type)
{
    Type type3;
    if (type == null)
    {
        throw new ArgumentNullException("type");
    }
    RuntimeType castType = type as RuntimeType;
    if (castType == null)
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
    }
    object element = this.GetElement(name, out type3);
    if (RemotingServices.IsTransparentProxy(element))
    {
        if (RemotingServices.ProxyCheckCast(RemotingServices.GetRealProxy(element), castType))
        {
            return element;
        }
    }
    else if ((object.ReferenceEquals(type3, type) || type.IsAssignableFrom(type3)) || (element == null))
    {
        return element;
    }
    return this.m_converter.Convert(element, type);
}
Другие вопросы по тегам