2

使用 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]”、finalType.MemberType 为“NestedType”且 finalType.underlyingType 为“{T}”时,在 ValueMember.cs 的第 322 行为此类型返回 null。

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

如果这确实是可以预料的,那么我最好的解决方法是什么?

4

2 回答 2

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;}
    ...
}

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

于 2013-07-04T23:08:13.333 回答
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
}
于 2013-10-11T22:00:52.330 回答