У меня возникло затруднение при попытке сериализации этой структуры данных:
protected string EngineQualifiedName
{
get { return Engine == null ? null : Engine.AssemblyQualifiedName; }
set { Engine = value == null? null : Type.GetType(value); }
}
public Type Engine { get; protected set; }
public string Method { get; protected set; }
public Type[] ParameterTypes { get; protected set; }
Проблема, очевидно, связана с сериализацией ParameterTypes. Читая о других подобных проблемах здесь в переполнении стека, я написал такой форматировщик:
public static IFormatter Formatter(IEnumerable<Type> paramTypes)
{
RuntimeTypeModel.Default.Add(typeof(ProtoBufRequest), true).Add(1, "ParameterCompositeValues").Add(2, "EngineQualifiedName").Add(3, "Method");
var ct = RuntimeTypeModel.Default.Add(typeof(CompositeType), true);
var ctType = typeof (CompositeType<>);
var j = 0;
foreach (var paramType in paramTypes)
{
try
{
RuntimeTypeModel.Default.Add(paramType, true);
}
catch
{ }
ct.AddSubType(j + 4, ctType.MakeGenericType(paramType));
j++;
}
return RuntimeTypeModel.Default.CreateFormatter(typeof (ProtoBufRequest));
}
И я использовал эти свойства и класс для маскировки массива типа:
private CompositeType[] ParameterCompositeValues
{
get
{
if (ParameterValues == null)
return null;
var create = typeof (CompositeType).GetMethod("Create");
return
ParameterValues.Select(
(t, i) => (CompositeType) create.MakeGenericMethod(ParameterTypes[i]).Invoke(null, new[] {t})).ToArray();
}
set
{
ParameterValues = value == null ? null : value.Select(v => v.Value).ToArray();
}
}
[ProtoContract(UseProtoMembersOnly = true)]
internal abstract class CompositeType
{
protected abstract object ValueImpl { get; set; }
public object Value
{
get { return ValueImpl; }
set { ValueImpl = value; }
}
public static CompositeType<T> Create<T>(T value)
{
return new CompositeType<T> {Value = value};
}
}
[ProtoContract(UseProtoMembersOnly = true)]
internal class CompositeType<T> : CompositeType
{
[ProtoMember(1)]
public new T Value { get; set; }
protected override object ValueImpl
{
get { return Value; }
set { Value = (T) value; }
}
}
Моя проблема на самом деле заключается в том, что, когда я пытаюсь сериализовать классы обобщения (например, Speaker, где T не известен), форматировщик сталкивается с некоторыми проблемами, и при десериализации я получаю пустой класс со всеми его значениями ноль. Я делаю что-то неправильно?
Универсальные классы корректно сериализуются, но если я попытаюсь настроить их таким образом, система сообщений не сможет правильно сериализоваться и десериализоваться: \
Буду признателен за любую помощь!