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);
}