Вопрос

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

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

struct Foo {
    float bar;

    union {
        int killroy;
        float fubar;
    } as;
}
Это было полезно?

Решение

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

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

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

Более подробная информация о профсоюзах в учебное пособие по созданию структуры

Другие советы

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

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

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

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

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

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

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

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

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

или;

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

Лично я бы проигнорировал ОБЪЕДИНЕНИЕ всех вместе и реализовал Killroy и Fubar как отдельные поля

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

Использование ОБЪЕДИНЕНИЯ экономит 32 бита памяти, выделенной int .... в наши дни приложение не будет создавать или прерывать работу.

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

    public float fubar
    {
        get{ return (float)killroy;}
        set{ killroy = (int)value;}
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top