So there's no confusion, when I talk through my issue I am doing so as someone who is using the compiled classes that result from Bond schemas (that is to say I use "class" instead of "struct", etc.). I feel like it makes more cognitive sense to think of it this way.
I am using Microsoft Bond and I have a main class that has several properties, one of which is an instance of a derived class.
When creating an instance of the main class I have no problem setting the property to an instance of the derived class; however when I deserialize from binary back into the main class the property is now seen as its base class.
I have tried to cast it as the derived class but that throws a runtime exception.
The examples for using derived classes in the Bond documentation/manual have you specifying the derived class at the time of deserialization, but I am not deserializing just the derived class but the main class.
Here's an example of how I have the bond schema set up
struct BaseExample
{
0: int property1;
}
struct DerivedExample : BaseExample
{
0: int property2;
}
struct MainExample
{
0: BaseExample mainProperty;
}
In usage I am setting mainProperty to an instance of the DerivedExample class. What I'd expect is that after deserialization, mainProperty is still of type DerivedExample (containing property2) but what I am seeing instead is mainProperty is of type BaseExample (and doesn't contain property2)
Am I forced to use generics to do this or is there something I am missing?
EDIT: Adding examples
My code that uses the classes generated from the Bond schemas is like this.
We have a calling service that creates a message of this type and uses Bond to serialize it into a byte array before sending it on a stream.
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);
Now we have a receiving service that is going to take this message off the stream and use Bond to deserialize it back into an object.
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
}
Full disclosure: I am actually using F# but I figured it would be better to do these in C#