Почему некоторые встроенные типы не работают, когда я компилирую typeModel? - PullRequest
2 голосов
/ 27 февраля 2020

Когда я компилирую, словарь модели Type перестает работать.

    [Test]
    public void TestCompileSerialization()
    {
        var data = new Dictionary<int, int>();
        data[1] = 1;

        var typeModel = TypeModel.Create();
        var compiledTypeModel = typeModel.Compile();

        using (var memory = new MemoryStream())
        {
            compiledTypeModel.Serialize(memory, data);
        }
    }

Этот тест выдает

Type is not expected, and no contract can be inferred: System.Collections.Generic.KeyValuePair`2[[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]

Нужно ли мне добавлять каждый словарь, который я хочу сериализовать, в TypeModel или там? Есть ли другие способы?

Кстати, я не понимаю, почему я должен все публиковать c, когда я хочу прекомпилировать сериализаторы?

1 Ответ

2 голосов
/ 27 февраля 2020

Да, когда вы создаете свою собственную модель типа, вы должны заранее указать ей, что включать, иначе не будет знать, что поддерживать . В идеале это включает в себя все типы, которые вы бы сериализовали как root типов, поэтому: если вы собираетесь сериализовать словарь: расскажите ему . Внутри protobuf- net v2 на самом деле не является словарями для особых случаев - он видит их в виде последовательности типа списка (KeyValuePair<TKey, TValue>), которая выглядит очень похожей на тип, о котором можно догадаться как о «кортеж»; protobuf- net v3 знает о словарях больше, но ... вам все же лучше рассказать об этом заранее.

Кстати, я не понимаю, почему Мне нужно все опубликовать c, когда я хочу прекомпилировать сериализаторы?

Есть два типа прекомпиляции; возможно, вы на самом деле просто хотите CompileInPlace() (а не Compile()), который сохраняет существующий RuntimeTypeModel, но использует IL-emit под крышками для создания легких методов подкладки для выполнения работы; при использовании этого подхода можно обойти проверки проверки доступности, что позволяет мне получить доступ к чему-либо, кроме public c; однако, когда вы используете Compile(), вы создаете реальные типы в реальной сборке (просто: в памяти), и когда вы делаете , что : вы не можете обойти проверки доступности (и несколько других проверочных проверок); это означает, что я подчиняюсь тем же правилам, что и вы, скажем, в компиляторе C#: если он не опубликован c, я не могу его трогать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...