Бинарная сериализация : ISerializable - C#
Формулировка задачи:
Наблюдаю следующий эксепшин:
System.InvalidCastException: Объект должен реализовывать интерфейс IConvertible.
По идее надобности в конвертере нет , ведь ровно в каком типе я сериализую поля , ровно в таком же десериализую.
Декомпиляция метода GetValue дала :
И мой код :
Что делать!???
[SecuritySafeCritical] public object GetValue(string name, Type type) { if ((object) type == null) throw new ArgumentNullException(nameof (type)); RuntimeType castType = type as RuntimeType; if (castType == (RuntimeType) null) throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType")); Type foundType; object element = this.GetElement(name, out foundType); if (RemotingServices.IsTransparentProxy(element)) { if (RemotingServices.ProxyCheckCast(RemotingServices.GetRealProxy(element), castType)) return element; } else if ((object) foundType == (object) type || type.IsAssignableFrom(foundType) || element == null) // по идее это условие при true решает проблему return element; return this.m_converter.Convert(element, type); }
/// <summary> /// Базовый класс. Представляет математическое выражение /// </summary> public abstract class MathExpression : ISerializable { public static readonly Const One = new Const("1", 1); public static readonly Const Pi = new Const("Pi", Math.PI); public bool IsSaveExtendedInfo { get; set; } public Collection<Quantity> IncludedQuantities { get; protected set; } /// <summary> /// Возвращает значение аргумента текущего выражения /// </summary> /// <param name="index">Индекс параметра</param> protected BigDecimal this[uint index] => Members[index].Calculate(); protected MathExpression[] Members; protected MathExpression(SerializationInfo si, StreamingContext sc) { try { IncludedQuantities = (Collection<Quantity>) si.GetValue(nameof(IncludedQuantities), typeof(Collection<Quantity>)); IsSaveExtendedInfo = true; } catch (SerializationException) { IsSaveExtendedInfo = false; } Members = (MathExpression[]) si.GetValue(nameof(Members), typeof(MathExpression[])); } protected MathExpression() { } /// <summary> /// Рассчитывает значение выражения /// </summary> /// <returns></returns> public abstract BigDecimal Calculate(); public abstract MathExpression Clone(); protected void InitExpression(params MathExpression[] members) { var quantities = new List<Quantity>(); foreach (var el in members) foreach (var quantity in el.IncludedQuantities) if (!quantities.Contains(quantity)) quantities.Add(quantity); IncludedQuantities = new Collection<Quantity>(quantities); Members = members; } public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue(nameof(Members), Members); if (IsSaveExtendedInfo) info.AddValue(nameof(IncludedQuantities), typeof(Collection<Quantity>)); } } [Serializable] public class Quantity : MathExpression { public string Name { get; } public IUnit Unit { get; set; } private BigDecimal _value; Quantity(string name) { Name = name; IncludedQuantities = new Collection<Quantity>(new[] {this}); } public Quantity(string name, IUnit unit) : this(name) => Unit = unit; protected Quantity(SerializationInfo si, StreamingContext sc) { IncludedQuantities = new Collection<Quantity>(new[] {this}); IsSaveExtendedInfo = true; Name = si.GetString("Name");//тоже будет ошибка , если использовать GetValue Unit = (IUnit) si.GetValue(nameof(Unit), typeof(IUnit));//ошибка } public void SetValue(BigDecimal value, IUnit unit) { _value = value; Unit = unit; } public void SetValue(BigDecimal value) => _value = value; public void ConvertTo(IUnit unit) { _value *= Unit.GetConversionRatio(unit); Unit = unit; } public override void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue(nameof(Name), typeof(string)); info.AddValue(nameof(Unit), typeof(IUnit)); } public override BigDecimal Calculate() => _value; public override MathExpression Clone() { var result = new Quantity(Name, Unit); result.SetValue(_value); return result; } public override string ToString() => Name; }
Решение задачи: «Бинарная сериализация : ISerializable»
textual
Листинг программы
public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue(nameof(Members), Members); // Здесь было правильно, другие были с ошибками if (IsSaveExtendedInfo) info.AddValue(nameof(IncludedQuantities), IncludedQuantities); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д