Преобразование типа Паскаля в C #

Я пытаюсь преобразовать тип Pascal в C #. Я посмотрел в Google, но мне не удалось найти ответ, возможно, потому, что я неправильно гуглил, так что извините, если это дубликат.

У меня есть эти два типа Паскаля:

type
  TVector3i = array [0..2] of longint;

  Tcolface = packed record
    A, B, C: word;
    SurfaceA, SurfaceB: word;
  end;

Я знаю

Tcolface = packed record
  A, B, C: word;
  SurfaceA, SurfaceB: word;
end;

преобразуется в:

struct Tcolface {
  ushort A, B, C;
  ushort SurfaceA, SurfaceB;
}

но как TVector3i = array [0..2] of longint; конвертируется?

Я пытаюсь избежать использования / написания класса, так как при преобразовании остальной части кода Паскаля он будет ожидать тип в виде массива, и я стараюсь не преобразовывать его в .x .y и .z.

Я думал о том, чтобы сделать float[] variablename = new float[3];, но как только я получаю List<float[]> variblename, все становится немного сложнее.

Полный код:

TVector3i = array [0..2] of Longint;
TVector3f = array [0..2] of Single;
TVector3d = array [0..2] of Double;

TVector4i = array [0..3] of Longint;
TVector4f = array [0..3] of Single;
TVector4d = array [0..3] of Double;

TMatrix3i = array [0..2] of TVector3i;
TMatrix3f = array [0..2] of TVector3f;
TMatrix3d = array [0..2] of TVector3d;

TMatrix4i = array [0..3] of TVector4i;
TMatrix4f = array [0..3] of TVector4f;
TMatrix4d = array [0..3] of TVector4d;

Поэтому я стараюсь избегать занятий: D


person D-Bennett    schedule 23.07.2015    source источник


Ответы (2)


как TVector3i = array [0..2] of longint; конвертируется?

Прямого эквивалента нет. TVector3i - это псевдоним статического массива. В C # нет аналогичных псевдонимов для массивов. Лучшее, что вы можете сделать, - это объявить struct, который содержит массив int[] внутри и предоставляет [] индексатор для большей синтаксической совместимости с кодом Паскаля:

struct TVector3i
{
    private int[] arr = new int[3];

    public int this[int i]
    {
        get
        {
            return arr[i];
        }
        set
        {
            arr[i] = value;
        }
    }
}

Обновление: на основе ваших примеров попробуйте что-нибудь вроде этого:

struct TVector3<T>
{
    private T[] arr = new T[3];

    public T this[int i]
    {
        get
        {
            return arr[i];
        }
        set
        {
            arr[i] = value;
        }
    }
}

struct TVector4<T>
{
    private T[] arr = new T[4];

    public T this[int i]
    {
        get
        {
            return arr[i];
        }
        set
        {
            arr[i] = value;
        }
    }
}

using TVector3i = TVector3<int>;
using TVector3f = TVector3<float>;
using TVector3d = TVector3<double>;

using TVector4i = TVector4<int>;
using TVector4f = TVector4<float>;
using TVector4d = TVector4<double>;

using TMatrix3i = TVector3<TVector3i>;
using TMatrix3f = TVector3<TVector3f>;
using TMatrix3d = TVector3<TVector3d>;

using TMatrix4i = TVector4<TVector4i>;
using TMatrix4f = TVector4<TVector4f>;
using TMatrix4d = TVector4<TVector4d>;
person Remy Lebeau    schedule 23.07.2015
comment
Это умный способ манипулировать структурой, я отредактировал свой вопрос с помощью некоторого примера кода внизу, как это работает с TMatrix3i и TVector3i, используйте TVector3i вместо int? - person D-Bennett; 23.07.2015
comment
Это сократит количество строк: D Кажется, я получаю эту ошибку, есть идеи? - person D-Bennett; 23.07.2015
comment
Кроме того, public T this[int i] должен быть public T this[T i] - person D-Bennett; 23.07.2015
comment
@ D-Bennett Я уверен, что ты сможешь написать остальной код самостоятельно. Вы можете прочитать документацию на MSDN. Мне кажется, вы больше заинтересованы в том, чтобы кто-то другой предоставил вам весь ваш код, а не в понимании. На вашем месте я бы немного замедлился и рассмотрел последствия использования ссылочного типа для хранения данных. - person David Heffernan; 23.07.2015
comment
@ Д-Беннет: Нет, [int i] не обязательно должно быть [T i]. Все массивы в типах Pascal индексируются целыми числами, таким образом [int i] в индексаторах структур C #. Прочтите документацию об индексаторах. Также прочтите документацию о using директиве, в частности: Правая сторона директивы using alias всегда должна быть полностью определенным типом., поэтому вам, вероятно, не хватает некоторых пространств имен, в которых вы объявляете эти типы. - person Remy Lebeau; 23.07.2015
comment
@DavidHeffernan Я не просил кого-нибудь написать для меня код, код, который я сейчас использую, - это тот же код, который вы предложили. Я тоже читал комментарии к вашему ответу. - person D-Bennett; 23.07.2015

Вероятно, есть веская причина сделать это типом значения. Это означает, что оператор присваивания является копией значения, а не ссылочной копией. Итак, структура может быть такой:

struct Vector3i
{
    int X;
    int Y;
    int Z;
}

Вы обязательно добавите к этому типу все методы, которые вам нужны, чтобы обеспечить полезные для вас операции. Например, оператор [] для удобства индексированного доступа.

person David Heffernan    schedule 23.07.2015
comment
Однако OP прямо сказал: я пытаюсь не преобразовывать это в .x .y и .z. Поскольку TVector3i - это массив, код Паскаля будет использовать индексы для доступа к значениям. Переход на структуру x/y/z означает переписывание логики кода, а не просто перенос ее на другой язык. - person Remy Lebeau; 23.07.2015
comment
Привет, я отредактировал свой вопрос внизу, чтобы попытаться объяснить, почему я пытаюсь избегать классов: D (и почему в примере используется float of int) - person D-Bennett; 23.07.2015
comment
Это не класс. Это структура. Если вам нужен оператор [], добавьте его. Я не думаю, что вы понимаете последствия перехода от типа значения к типу ссылки. Подождите, пока вы не воспользуетесь оператором =. В любом случае, вы решили, что вам не нравится такой подход, так что ничего страшного. Вы уже приняли ответ перед обсуждением. Удачи. - person David Heffernan; 23.07.2015
comment
Привет, это был подход, который я имел в виду изначально, и пытался избежать его, если возможно, но спасибо за предложение :) в чем проблема с оператором =? - person D-Bennett; 23.07.2015
comment
Я объясняю это в своем первом абзаце. Знаете ли вы разницу между ссылочными типами и типами значений? - person David Heffernan; 23.07.2015
comment
На C # или на паскале? Думаю, я понимаю, ссылка - это указатель на объект, а значение - это просто значение, верно? - person D-Bennett; 23.07.2015
comment
Важно думать, что происходит с =. Копирует ли значение или ссылку на тот же объект. - person David Heffernan; 23.07.2015
comment
В вашем коде Delphi используются типы значений. Если вы переключитесь на ссылочный тип (массив является ссылочным типом), то семантика вашего кода изменится неизмеримо. Чтобы добиться дословного переноса, нужно объявить структуру, как это сделал я, а затем добавить индексатор. - person David Heffernan; 23.07.2015
comment
@ D-Bennett, если производительность важна, лучше всего использовать тип значения. - person LU RD; 23.07.2015
comment
@LURD Я бы сказал, что семантика - это важная вещь. Аскер хочет как можно быстрее выполнить перенос большого количества кода Delphi. Очень сложно сделать это быстро или даже безопасно, если вы переключитесь с типа значения на тип ссылки. - person David Heffernan; 23.07.2015
comment
Чем variable.x == 1 отличается от переменной [0] == 1, я понимаю, что переменная variable == будет сравниваться со ссылками, но это не используется в коде. - person D-Bennett; 23.07.2015
comment
Я говорю о назначении, =. Во всяком случае, вы закрыли вопрос. - person David Heffernan; 23.07.2015