Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Union type in C# #59

Closed
grant-d opened this issue Apr 27, 2015 · 3 comments
Closed

Union type in C# #59

grant-d opened this issue Apr 27, 2015 · 3 comments
Labels

Comments

@grant-d
Copy link

grant-d commented Apr 27, 2015

If I use an explict struct (see below) and manually decorate it with the [bond] attributes, will Bond do the right things in terms of de/serialization. In other words, in the snippet below will the populated field (both at offset 0) maintain fidelity across the wire?

Background: I have an efficient in-memory representation of data (the struct below is just one part of that representation). I also need an efficient wire representation of the same data, but not sure whether I need a completely separate struct for Bond or whether I can just 're-use' the existing struct.

 [Bond.Schema(...)]
 [StructLayout(LayoutKind.Explicit, Pack=1)]
    internal struct Union
    {
        #region Blittable

        [Bond.Id(0)]
        [FieldOffset(0)]
        public Byte Byte;

        [Bond.Id(1)]
        [FieldOffset(0)]
        public Int16 Int16;

...etc...
@sapek
Copy link
Contributor

sapek commented Apr 28, 2015

In general this will not do what you want.

Bond will optimize size of serialized data by omitting fields set to the default value when serializing. This means that you can effectively use a schema with multiple fields like a union from wire format perspective (only the one field that is set will be serialized). However when you store all the fields at the same offset, like in your example, then they will likely all have non-default values and thus will all be serialized. There are also other pitfalls with this approach if the field types are anything other than numeric types. You might actually get invalid value after deserialization.

If the Union has numeric fields and is something that you use as a field/element type in larger schema(s) (i.e. you don't serialize Union as a top level object) then you could use type alias facility to get very efficient representation. For example you could define Union as an alias of uint64 and then provide a converter between uint64 and the C# Union struct. BTW, I would suggest trying type aliases using Bond codegen first, even if you want to manually annotate your C# types in your actual project.

@grant-d
Copy link
Author

grant-d commented Apr 30, 2015

Thanks Adam

Sounds good - I will essentially create a Bond DTO for the wire.

A few questions:

  1. Interested in why you recommend idl-first, as opposed to manual-decoration?

  2. Is it faster to use an ArraySegment<> to represent (say) Decimal, or would it be equivalent to use a custom struct such as:

struct BondDecimal
{
    00: required Int32 D0;
    01: required Int32 D1;
    02: required Int32 D2;
    03: required Int32 D3;
}

@sapek
Copy link
Contributor

sapek commented May 4, 2015

  1. The type annotation for complex type aliasing cases can get tricky. The type alias IDL using syntax and the compiler's type alias mapping --using command line option are just easier.
  2. Using blob should be faster and will use less space.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants