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