'NotSupportedException: Type cannot be represented as a default value' 更新 protobuf-net 后

'NotSupportedException: Type cannot be represented as a default value' after updating protobuf-net

更新到最新版本的 protobuf-net (2.4.0) 后,一切不再有效:

System.InvalidOperationException: It was not possible to prepare a serializer for: QueryContainer

多年来在 2.0.0.668 版本上一切正常,似乎在 2.2.1 版本上也能正常工作,但 2.3.0 和更新版本会导致此问题。

有什么变化或我一直做错了什么? :-) 我构建了一个小的复现,结果是:

It was not possible to prepare a serializer for: ProtoRepro.Program+QueryContainer InnerException: Type cannot be represented as a default value: System.Collections.Generic.KeyValuePair`2[[ProtoRepro.Program+Query, ProtoRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Double, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]

using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace ProtoRepro {

  internal class Program {
    private static void Main(string[] args) {
      try {
        RuntimeTypeModel.Default[typeof(QueryContainer)].CompileInPlace();
        // we get here with version 2.2.1 and lower
        Console.WriteLine("Everything is fine!");
      } catch (InvalidOperationException ioex) {
        Console.Write(ioex.ToString());
      } catch (NotSupportedException nsex) {
        Console.Write(nsex.ToString());
      }
    }

    [Serializable, ProtoContract]
    public class QueryContainer {
      private QueryContainer() { }
      [ProtoMember(1, OverwriteList = true)]
      public Dictionary<string, KeyValuePair<Query, double>> QueryAndWeightPerVariable { get; protected set; }
    }

    [Serializable, ProtoContract]
    public class Query {
      [ProtoMember(1)]
      public QueryValue QueryValue { get; set; }
      protected Query() { }
      public Query(QueryValue queryValue) {
        QueryValue = queryValue;
      }
    }

    [Serializable, ProtoContract]
    public class QueryValue {
      [ProtoMember(1)]
      public object Value { get; set; }
      protected QueryValue() { }
      public QueryValue(object value) {
        Value = value;
      }
    }
  }
}

我将不得不设置一个本地测试来深入了解它,但这里的更改很可能与 "map" 行为有关。因此,您可以 尝试 添加

[ProtoMap(DisableMap = true)]

给字典成员。如果这是一个猜测,我深表歉意(尤其是如果我错了!),但要深入研究它必须等到我有空的时候。在 GitHub 上将其记录为问题可能也很有用。