自定义泛型类型是否适用于预编译?

时间:2013-07-04 22:42:34

标签: .net protobuf-net

使用JIT时,以下类型似乎可以使用Protobuf-net序列化。 我有它在Windows,Mac和Android上工作。

// Stores a pair of values
[ProtoContract]
public class OneTwo<T>
{
    [ProtoMember(1)]
    public T One = default(T);

    [ProtoMember(2)]
    public T Two= default(T);

    public OneTwo() { }

    public OneTwo(T One, T Two)
    {
        this.One = One;
        this.Two = Two;
    }   
}

但是现在我试图让它在iOS上运行,因此使用“预编译器”。 因为它是错误的,我尝试从源代码运行预编译器并发现

IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType, OverwriteList, true);
当finalType.DeclaringType为“OneTwo'1 [T]”时,

在ValueMember.cs的第322行返回null,finalType.MemberType为“NestedType”,finalType.underlyingType为“{T}”。< / p>

我想知道在使用JIT在运行时创建模型但是在尝试为AOT预编译时失败时是否应该期望这个工作?

如果确实如此,那么我最好的工作是什么呢?

2 个答案:

答案 0 :(得分:1)

就protobuf-net而言,OneTwo<Foo>OneTwo<Bar>基本无关,OneTwo<>(开放泛型类型)毫无意义。它是在第一次看到每种类型时为每个OneTwo<{something}>分别准备一个策略。

您最好的网络是将预编译欺骗为了解您打算在运行时使用的T。也许:

[ProtoContract, Obsolete("this is not the class you are looking for", true)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public class BagOfEvil {
    [ProtoMember(1)] public OneTwo<Foo> Foo {get;set;}
    [ProtoMember(2)] public OneTwo<Bar> Bar {get;set;}
    ...
}

现在它知道你将使用的具体类型。

答案 1 :(得分:0)

我能够通过编辑预编译程序的Program.cs来解决这个问题,不向模型添加任何开放的泛型类型,因为我有其他使用封闭泛型类型的类型它将自动生成所有需要的封闭的通用类型序列化代码

在PreCompileContext.Execute()

foreach (var type in toAdd)
{
    if (type.IsGenericTypeDefinition) // dont add open generic types to model
        continue;

    Console.WriteLine("Adding " + type.FullName + "...");

    var tmp = model.Add(type, true);

    if (metaType == null) metaType = tmp; // use this as the template for the framework version
}