Бинарная сериализация : 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);
        }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4 из 5
Похожие ответы