5

Duplicate of C++ union in C#

Is there a C# equivalent to the C union typedef? What is the equivalent of the following in C#?

typedef union byte_array
{
    struct{byte byte1; byte byte2; byte byte3; byte byte4;};
    struct{int int1; int int2;};
};byte_array
Community
  • 1
  • 1

3 Answers3

7

C# doesn't natively support the C/C++ notion of unions. You can however use the StructLayout(LayoutKind.Explicit) and FieldOffset attributes to create equivalent functionality. Note that this works only for primitive types like int and float.

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Explicit)]
struct byte_array
{
    [FieldOffset(0)]
    public byte byte1;

    [FieldOffset(1)]
    public byte byte2;

    [FieldOffset(2)]
    public byte byte3;

    [FieldOffset(3)]
    public byte byte4;

    [FieldOffset(0)]
    public short int1;

    [FieldOffset(2)]
    public short int2;
}
M. Jahedbozorgan
  • 6,914
  • 2
  • 46
  • 51
  • 1
    Actually, apart from native primitive types, this would also work for user-created values, defined as Structs. See here: http://stackoverflow.com/documentation/c%23/5626/how-to-use-c-sharp-structs-to-create-a-union-type-similar-to-c-unions#t=201608241340099784116 – Milton Hernandez Aug 24 '16 at 13:41
  • The docs mentioned in the previous comment by Milton (who is also correct) can (at this time) be found here: https://sodocumentation.net/csharp/topic/5626/how-to-use-csharp-structs-to-create-a-union-type---similar-to-c-unions- – Maxim Paperno Mar 13 '22 at 21:29
1

Using the StructLayout attribute, it would look a little like this:

    [StructLayout(LayoutKind.Explicit, Pack=1)]
    public struct ByteArrayUnion
    {
        #region Byte Fields union

        [FieldOffset(0)]
        public byte Byte1;

        [FieldOffset(1)]
        public byte Byte2;

        [FieldOffset(2)]
        public byte Byte3;

        [FieldOffset(3)]
        public byte Byte4;

        #endregion

        #region Int Field union

        [FieldOffset(0)]
        public int Int1;

        [FieldOffset(4)]
        public int Int2;

        #endregion
    }
Erich Mirabal
  • 9,860
  • 3
  • 34
  • 39
1

Your question does not specify what your purpose is. If you are looking to marshal the data to pinvoke, then the 2 above answers are correct.

If not, the you simply do:

class Foo
{
  object bar;
  public int Bar {get {return (int)bar; } }
  ...
}
leppie
  • 115,091
  • 17
  • 196
  • 297