Pregunta

Estoy traduciendo una biblioteca escrita en C++ a C# y la palabra clave "unión" existe una vez.En una estructura.

¿Cuál es la forma correcta de traducirlo a C#?¿Y qué hace?Se parece a esto;

struct Foo {
    float bar;

    union {
        int killroy;
        float fubar;
    } as;
}
¿Fue útil?

Solución

Puede utilizar diseños de campo explícitos para eso:

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

No probado.La idea es que dos variables tengan la misma posición en tu estructura.Por supuesto, sólo puedes utilizar uno de ellos.

Más información sobre sindicatos en tutorial de estructura

Otros consejos

Realmente no puedes decidir cómo lidiar con esto sin saber algo sobre cómo se usa.Si simplemente se usa para ahorrar espacio, puede ignorarlo y simplemente usar una estructura.

Sin embargo, no suele ser por eso que se utilizan los sindicatos.Hay dos razones comunes para usarlos.Una es proporcionar 2 o más formas de acceder a los mismos datos.Por ejemplo, una unión de un int y una matriz de 4 bytes es una (de muchas) formas de separar los bytes de un entero de 32 bits.

La otra es cuando los datos de la estructura provienen de una fuente externa, como un paquete de datos de red.Por lo general, un elemento de la estructura que encierra la unión es un ID que indica qué tipo de unión está vigente.

En ninguno de estos casos se puede ignorar ciegamente la unión y convertirla en una estructura donde los dos (o más) campos no coincidan.

En C/C++, la unión se usa para superponer diferentes miembros en la misma ubicación de memoria, por lo que si tiene una unión de un int y un float, ambos usan los mismos 4 bytes de memoria para almacenar, obviamente escribir en uno corrompe al otro (ya que int y float tienen una disposición de bits diferente).

En .Net, Microsoft optó por la opción más segura y no incluyó esta característica.

EDITAR:excepto para la interoperabilidad

Si estás usando el union para asignar los bytes de uno de los tipos al otro, entonces en C# puedes usar BitConverter en cambio.

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

o;

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

Personalmente, ignoraría la UNIÓN por completo e implementaría Killroy y Fubar como campos separados.

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

El uso de UNION ahorra 32 bits de memoria asignados por el int... no va a hacer ni deshacer una aplicación en estos días.

public class Foo
{
    public float bar;
    public int killroy;

    public float fubar
    {
        get{ return (float)killroy;}
        set{ killroy = (int)value;}
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top