Так что нет никакой путаницы, когда я говорю по моей проблеме, я делаю это как кто-то, кто использует скомпилированные классы, которые являются результатом схем Bond (то есть Я использую «класс» вместо «struct» и т. Д.). Я чувствую, что это делает больше когнитивного смысла думать об этом таким образом.Как правильно использовать производные классы в качестве полей объекта Microsoft Bond
Я использую Microsoft Bond, и у меня есть основной класс, который имеет несколько свойств, один из которых является экземпляром производного класса.
При создании экземпляра основного класса у меня нет проблем с установкой свойства экземпляру производного класса; однако, когда я deserialize из двоичного обратно в основной класс, свойство теперь рассматривается как его базовый класс.
Я попытался использовать его как производный класс, но это исключает исключение во время выполнения.
В примерах использования производных классов в документации/руководстве Bond вы указываете производный класс во время десериализации, но я не десериализую только производный класс, а основной класс.
Вот пример того, как у меня есть схема связи создана
struct BaseExample
{
0: int property1;
}
struct DerivedExample : BaseExample
{
0: int property2;
}
struct MainExample
{
0: BaseExample mainProperty;
}
В использовании я устанавливаю mainProperty к экземпляру класса DerivedExample. То, что я бы ожидать, что после десериализации, mainProperty еще из DerivedExample типа (содержащий свойство2), но то, что я вижу вместо этого mainProperty имеет BaseExample типа (и не содержит свойство2)
я вынужден использовать дженерики, чтобы сделать это, или есть что-то, чего я не хватает?
EDIT: Добавление примеров
Мой код, который использует классы, полученные от схем Бонде, как это.
У нас есть служба вызова, которая создает сообщение этого типа и использует Bond для сериализации в байтовый массив перед отправкой его потоку.
var message = new MainExample();
var derivedExample = new DerivedExample()
{
property1 = 1,
property2 = 2,
};
message.mainProperty = derivedExample;
// This block is all from the Bond examples
var output = new OutputBuffer();
var writer = new CompactBinaryWriter<OutputBuffer>(output);
Serialize.To(writer, message);
SendMessage(output.Data.Array);
Теперь у нас есть принимающий сервис, который собирается принять это сообщение от потока и использовать Bond десериализовать его обратно в объект.
void HandleMessage(byte[] messageBA)
{
// This block is all from the Bond examples
var input = new InputBuffer(messageBA);
var reader = new CompactBinaryReader<InputBuffer>(input);
MainExample message = Deserialize<BondEvent>.From(reader);
// mainProperty is now of type BaseExample and not DerivedExample
message.mainProperty.property1; // is accessable
message.mainProperty.property2; // will not compile
DerivedExample castedProperty = message.mainProperty as DerivedExample; // fails at runtime
}
Полное раскрытие: Я на самом деле с помощью F #, но я полагал, что это было бы лучше сделать это в C#
Я не совсем уверен, что вы настраиваете на то, что и что вы видите, это неправильно.Можете ли вы отредактировать вопрос, чтобы показать, как вы создаете, устанавливаете, сериализуете, десериализируете и проверяете структуры? – chwarr
Я пересказывал некоторые вещи и добавлял примеры, мне жаль, что я не знаю, как сделать это проще объяснить. Дьявол определенно в деталях касается моего вопроса. Но если есть что-то конкретное, я могу прояснить, пожалуйста, дайте мне знать, и я попробую. Я убежден, что если я сериализую конкретную реализацию производного типа, десериализатор должен иметь возможность создавать экземпляр того же типа, который был сериализован. Я этого не вижу, так что либо я делаю это неправильно, либо это невозможно, и это прекрасно, мне просто нужно знать наверняка, прежде чем переключиться на использование дженериков (что действительно работает). – GoodGuyJim
Получил то, что мне нужно (редактирование структуры 'MainExample', которая изменила тип' mainProperty'), чтобы ответить на вопрос. – chwarr