Структура внутри Struct, способная изменять внутренний тип Struct

Здесь не так много объяснений, вот что у меня есть:

public struct PACKET_HEADER
    {
        public string computerIp;
        public string computerName;
        public string computerCustomName;
    };

    public struct PACKET
    {
        public PACKET_HEADER pktHdr;
        public PACKET_DATA pktData;
    };


    public struct PACKET_DATA
    {
        public Command command;
        public string data;  
    };

    public struct DATA_MESSAGE
    {
        public string message;
    };

    public struct DATA_FILE
    {
        public string fileName;
        public long fileSize;       
    };

В основном я хочу, чтобы поле данных в PACKET_DATA могло быть либо DATA_FILE, либо DATA_MESSAGE. Я знаю, что тип нужно изменить, но я не знаю, что делать, можно ли использовать дженерики?

конечный результат должен быть таким, чтобы я мог сделать либо:

pktData.data.fileName или pktData.data.message

РЕДАКТИРОВАТЬ

Я мог бы сделать:

public struct PACKET_DATA
{
    public Command command;
    public string data;
    public DATA_MESSAGE data_message;
    public DATA_FILE data_file;
};

и просто установить значение null для data_message или файла, когда они мне не понадобятся? как это повлияет на сериализацию / байтовый массив и отправляемые данные. Если бы я использовал классы, у меня не было бы такой же проблемы

РЕДАКТИРОВАТЬ 2

public struct PACKET_MESSAGE
{
    public PACKET_HEADER pktHdr;
    public Command command;
    public DATA_MESSAGE pktData;
};

public struct PACKET_FILE
{
    public PACKET_HEADER pktHdr;
    public Command command;
    public DATA_FILE pktData;
};

Редактировать 3

У меня есть стерилизатор и де-стерилизатор, который работает с моим исходным примером, если с этим нет проблем, то фактическая сериализация

РЕДАКТИРОВАТЬ 4

вроде бы все работает, за исключением одной вещи, которую мой сериализатор получает «Попытка чтения или записи в защищенную память. Это часто указывает на то, что другая память повреждена». gunna взгляните на него, когда опубликуете мое рабочее решение :)

РЕДАКТИРОВАТЬ 5

    public static byte[] Serialize(object anything)
    {
        int rawsize = Marshal.SizeOf(anything);
        byte[] rawdatas = new byte[rawsize];
        GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
        IntPtr buffer = handle.AddrOfPinnedObject();
        Marshal.StructureToPtr(anything, buffer, false);
        handle.Free();
        return rawdatas;
    }

    public static object Deserialize(byte[] rawdatas, Type anytype)
    {
        int rawsize = Marshal.SizeOf(anytype);
        if (rawsize > rawdatas.Length)
            return null;
        GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
        IntPtr buffer = handle.AddrOfPinnedObject();
        object retobj = Marshal.PtrToStructure(buffer, anytype);
        handle.Free();
        return retobj;
    } 

ОКОНЧАТЕЛЬНОЕ

Структуры:

public struct PACKET_HEADER
{
    public string computerIp;
    public string computerName;
    public string computerCustomName;
};

public struct PACKET
{
    public PACKET_HEADER pktHdr;
    public PACKET_DATA pktData;
};

public struct PACKET_DATA
{
    public Command command;
    public IDATA data;
    public T GetData<T>() where T : IDATA
    {
        return (T)(data);
    }
}

public interface IDATA { }

public struct DATA_MESSAGE : IDATA
{
    public string message;
}

public struct DATA_FILE : IDATA
{
    public string fileName;
    public long fileSize;
}

Как создать новый пакет (возможно, можно объединить вместе tbh):

    public static PACKET CreatePacket(Command command)
    {
        PACKET packet;
        packet.pktHdr.computerIp = Settings.ComputerIP;
        packet.pktHdr.computerName = Settings.ComputerName;
        packet.pktHdr.computerCustomName = Settings.ComputerCustomName;

        packet.pktData.command = command;
        packet.pktData.data = null;

        return packet;
    }

    public static PACKET CreatePacket(Command command, DATA_MESSAGE data_message)
    {
        PACKET packet;
        packet.pktHdr.computerIp = Settings.ComputerIP;
        packet.pktHdr.computerName = Settings.ComputerName;
        packet.pktHdr.computerCustomName = Settings.ComputerCustomName;

        packet.pktData.command = command;
        packet.pktData.data = data_message;

        return packet;
    }

    public static PACKET CreatePacket(Command command, DATA_FILE data_file)
    {
        PACKET packet;
        packet.pktHdr.computerIp = Settings.ComputerIP;
        packet.pktHdr.computerName = Settings.ComputerName;
        packet.pktHdr.computerCustomName = Settings.ComputerCustomName;

        packet.pktData.command = command;
        packet.pktData.data = data_file;

        return packet;
    }

(de ) сериализации выше. публичный класс Garage {частный список cars = new ArrayList (); ... } В настольном приложении есть ...

Допустим, у меня есть настольное приложение, которое действует как гараж для группы автомобилей:

@Entity
public class Garage {
    private List<Car> cars = new ArrayList<Car>();
    ...
}

В настольном приложении есть кнопка «моделирования», которая запускает новый поток и начинает звонить методы на Гараже, Машине, Колесе и т. д. Выполнение этой симуляции может занять до 10 минут. На данный момент у меня есть класс, который выглядит так:

beginTransaction();
Garage garage = garageDao.findGarage(1);
List<Car> cars = garage.getCars();
for (Car car : cars) {
    // call methods on the car to lazily fetch other things like wheels...
}
commitTransaction();

Этот код только «читает» и никогда не «пишет»

Таким образом, приведенное выше может занять много времени в зависимости от того, насколько сильно автомобили нуждаются в обслуживании. Пока происходит вышеуказанное, пользователь может продолжать работать с настольным приложением. Они могут выбрать изменение цвета автомобиля, который используется в вышеуказанной транзакции.

Мой вопрос заключается в том, предотвратит ли вышеуказанная длительная транзакция изменение цвета автомобиля? т.е. пользователь, изменяющий цвет автомобиля в настольном приложении, не сможет зафиксировать изменение, пока длинная транзакция не будет завершена?

5
задан digiarnie 20 December 2010 в 08:33
поделиться