C++ объединение в C#


я перевожу библиотеку, написанную на C++ в C#, и ключевое слово "union" существует один раз. В структуре.

Как правильно перевести его на C#? И что он делает? Это выглядит примерно так:

struct Foo {
    float bar;

    union {
        int killroy;
        float fubar;
    } as;
}
6   60   2008-09-24 16:20:32

6 ответов:

вы можете использовать явные макеты полей для этого:

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

непроверенными. Идея заключается в том, что две переменные имеют одинаковые позиции в структуре. Конечно, вы можете использовать только один из них.

больше информации о товарищества в структура учебника

вы не можете действительно решить, как справиться с этим, не зная ничего о том, как он используется. Если он просто используется для экономии места, то вы можете игнорировать его и просто использовать структуру.

однако это обычно не то, почему используются союзы. Есть две общие причины использовать их. Один из них-предоставить 2 или более способов доступа к одним и тем же данным. Например, объединение int и массива из 4 байт - это один (из многих) способов выделения байтов 32-битного целое число.

другой - это когда данные в структуре поступают из внешнего источника, такого как сетевой пакет данных. Обычно одним из элементов структуры, включающей объединение, является идентификатор, который сообщает вам, какой вкус объединения действует.

ни в одном из этих случаев вы не можете слепо игнорировать объединение и преобразовать его в структуру, где два (или более) поля не совпадают.

в C/C++ union используется для наложения разных членов в одном и том же месте памяти, поэтому, если у вас есть объединение int и float, они оба используют одни и те же 4 байта памяти для хранения, очевидно, запись в один портит другой (так как int и float имеют разную битовую компоновку).

в .Net Microsoft пошла с более безопасным выбором и не включила эту функцию.

редактировать: за исключением взаимодействия

лично я бы проигнорировал Союз все вместе и реализовал Killroy и Fubar как отдельные поля

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

использование объединения сохраняет 32 бита памяти, выделенной int....не собираюсь делать или ломать приложение в эти дни.

если вы используете union чтобы сопоставить байты одного из типов с другим, то в C# вы можете использовать .

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

или

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;}
    }
}