União C ++ em C #

Estou traduzindo uma biblioteca escrita em C ++ para C #, e a palavra-chave ‘union’ existe uma vez. Em uma estrutura.

Qual é a maneira correta de traduzi-lo em c #? E o que ele faz? Parece algo como isto;

struct Foo { float bar; union { int killroy; float fubar; } as; } 

    Você pode usar layouts de campo explícitos para isso:

     [StructLayout(LayoutKind.Explicit)] public struct SampleUnion { [FieldOffset(0)] public float bar; [FieldOffset(4)] public int killroy; [FieldOffset(4)] public float fubar; } 

    Não testado. A ideia é que duas variables ​​tenham a mesma posição em sua estrutura. Você pode, claro, usar apenas um deles.

    Mais informações sobre sindicatos no tutorial struct

    Você não pode realmente decidir como lidar com isso sem saber algo sobre como ele é usado. Se está meramente sendo usado para economizar espaço, então você pode ignorá-lo e apenas usar uma estrutura.

    No entanto, geralmente não é por isso que os sindicatos são usados. Existem dois motivos comuns para usá-los. Uma é fornecer duas ou mais maneiras de acessar os mesmos dados. Por exemplo, uma união de um int e um array de 4 bytes é uma (de muitas) maneiras de separar os bytes de um inteiro de 32 bits.

    A outra é quando os dados no struct vieram de uma fonte externa, como um pacote de dados de rede. Geralmente, um elemento da estrutura que envolve a união é um ID que informa qual sabor da união está em vigor.

    Em nenhum desses casos você pode ignorar cegamente a união e convertê-la em uma estrutura na qual os dois (ou mais) campos não coincidem.

    Em C / C ++ union é usado para sobrepor membros diferentes no mesmo local de memory, então se você tiver uma união de um int e um float ambos usam os mesmos 4 bytes de memory para armazenar, obviamente escrever para um corrompe o outro (desde int e float têm layout de bit diferente).

    Em .Net Microsoft foi com a escolha mais segura e não incluiu esse recurso.

    EDIT: exceto para interoperabilidade

    Pessoalmente, eu iria ignorar a UNIÃO todos juntos e implementar Killroy e Fubar como campos separados

     public struct Foo { float bar; int Kilroy; float Fubar; } 

    Usando um UNION salva 32 bits de memory alocados pelo int …. não vai fazer ou quebrar um aplicativo nos dias de hoje.

    Se você estiver usando a union para mapear os bytes de um dos tipos para o outro, então, em C #, você pode usar o BitConverter .

     float fubar = 125f; int killroy = BitConverter.ToInt32(BitConverter.GetBytes(fubar), 0); 

    ou;

     int killroy = 125; float fubar = BitConverter.ToSingle(BitConverter.GetBytes(killroy), 0); 
     public class Foo { public float bar; public int killroy; public float fubar { get{ return (float)killroy;} set{ killroy = (int)value;} } }