Преобразование записи варианта Delphi в структуру C # - PullRequest
4 голосов
/ 17 февраля 2012

Поскольку я пытаюсь кодировать приложение C # из существующего приложения, но разработанного в Delphi, Очень тяжело, но справился как-то до этого, но теперь я столкнулся с проблемой ...

Код Delphi содержит следующий код:

type  
  TFruit = record
    name : string[20];
    case isRound : Boolean of // Choose how to map the next section
      True  :
        (diameter : Single);  // Maps to same storage as length
      False :
        (length   : Single;   // Maps to same storage as diameter
         width    : Single);
  end;

т.е. запись варианта (с оператором case внутри) и соответственно запись и ее размер тоже. С другой стороны, я пытаюсь сделать то же самое в C # struct, но пока не удалось, я надеюсь, что кто-то может помочь мне здесь. Так что просто дайте мне знать, если есть какой-нибудь способ, которым я могу реализовать это в C #. Заранее спасибо ....

Ответы [ 3 ]

5 голосов
/ 17 февраля 2012

Вы можете использовать явную структуру структуры для репликации этой записи варианта Delphi. Однако я бы не стал беспокоиться, поскольку кажется маловероятным, что вы действительно хотите, чтобы присваивание diameter присваивалось также length и наоборот. Эта декларация Delphi выглядит так, как будто она датируется серединой 1990-х годов в стиле Delphi. Современный код Delphi редко пишется таким образом.

Я бы просто сделал это так:

struct Fruit
{
    string name;
    bool isRound;
    float diameter; // only valid when isRound is true
    float length;   // only valid when isRound is false
    float width;    // only valid when isRound is false
}

Более элегантный вариант - это класс со свойствами для каждого поля структуры. И вы бы устроили так, чтобы методы получения и установки свойств для 3-х чисел вызывали исключения, если к ним обращались с недопустимым значением isRound.

1 голос
/ 17 февраля 2012

Это зависит от того, что вы пытаетесь сделать.

Если вы просто пытаетесь создать соответствующую структуру, посмотрите на ответ Дэвида Хеффернана. В наши дни мало оснований для сопоставления двух полей друг над другом, если они действительно не представляют одну и ту же вещь. (Скажем, отдельные элементы или одинаковые элементы в массиве.)

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

Не только проблема Unicode, но и короткая строка Delphi не имеет соответствующей структуры в C #, и, следовательно, невозможно просто отобразить поле поверх нее.

Эта строка [20] на самом деле содержит 21 байт, однобайтовый код длины и затем 20 символов данных. Вы должны соблюдать код длины, поскольку нет гарантии того, что находится за пределами указанной длины - вы, скорее всего, найдете там мусор. (Подсказка: если запись будет записана на диск, всегда заполняйте поле перед добавлением в него новых данных. Это облегчает проверку файла на диске при отладке.)

Таким образом, вам нужно объявить два поля и написать код для обработки его на обоих концах.

Так как вы все равно должны это сделать, я бы пошел дальше и написал код для обработки всего остального, чтобы вообще исключить необходимость в небезопасном коде.

1 голос
/ 17 февраля 2012

Возможно, это поможет?

Это НЕ решение для копирования и вставки, обратите внимание, что смещения и размеры данных могут потребоваться изменить в зависимости от того, как структура Delphi объявлена ​​и / или выровнена.

[StructLayout(LayoutKind.Explicit)]
unsafe struct Fruit
{
    [FieldOffset(0)] public fixed char name[20];
    [FieldOffset(20)] public bool IsRound;
    [FieldOffset(21)] public float Diameter;
    [FieldOffset(21)] public float Length;
    [FieldOffset(25)] public float Width;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...