4

I'm trying to convert a Pascal type to C#. I have had a look around on Google, but I have not managed to find an answer, possibly because I am not googling correctly, so sorry if this is a duplicate.

I have these two Pascal types:

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

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

I know

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

converts to:

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

but how does TVector3i = array [0..2] of longint; convert?

I'm trying to avoid using/writing a class, as when I convert the rest of the Pascal code it will be expecting the type as an array, and I am trying to avoid converting that to .x .y and .z.

I did consider doing float[] variablename = new float[3];, but as soon as I get List<float[]> variblename it gets a bit more complex.

The full code is:

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;

Hence why I am trying to avoid classes :D

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
D-Bennett
  • 155
  • 10

2 Answers2

9

how does TVector3i = array [0..2] of longint; convert?

There is no direct equivalent. TVector3i is an alias for a static array. C# does not have similar aliasing for arrays. The best you can do is declare a struct that contains an int[] array inside of it, and provides an [] indexer for closer syntax compatibility with the Pascal code:

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

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

Update: based on your examples, try something like this:

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>;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • That's a clever way to manipulate a struct, I have edited my question with some example code at the bottom, how does this work with the TMatrix3i and TVector3i, use TVector3i instead of int? – D-Bennett Jul 23 '15 at 19:34
  • That will cut down on the line count :D [I seem to get this error](http://www.qsimg.co.uk/zeq2au), any ideas? – D-Bennett Jul 23 '15 at 20:05
  • Also, would `public T this[int i]` need to be `public T this[T i]` – D-Bennett Jul 23 '15 at 20:11
  • @D-Bennett I'm sure that you can write the rest of the code yourself. You could read the documentation on MSDN. It seems to me that you are more interested in somebody else provided all your code for you rather than understanding. If I were you I'd slow down a little and consider the implications of using a reference type to hold the data. – David Heffernan Jul 23 '15 at 20:14
  • 1
    @D-Bennett: No, `[int i]` would not need to be `[T i]`. All of the arrays in the Pascal types are indexed by integers, thus `[int i]` in the C# struct indexers. Read the documentation about [Indexers](https://msdn.microsoft.com/en-us/library/6x16t2tx.aspx). Also read the documentation about the [`using` directive](https://msdn.microsoft.com/en-us/library/sf0df423.aspx), in particular: "*The right side of a using alias directive must always be a **fully-qualified type**.*", so you are probably missing some namespaces where you are declaring these types. – Remy Lebeau Jul 23 '15 at 20:14
  • @DavidHeffernan I was not asking someone to "Write the code for me" the code I'm currently using is the same code you suggested. I have been reading the comments in your answer too. – D-Bennett Jul 23 '15 at 20:30
5

There's probably good reason to make this a value type. That means the assignment operator is a value copy rather than a reference copy. So the struct might be:

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

You'd surely add whatever methods you needed to this type to provide the operations that are useful to you. For instance an [] operator to make indexed access convenient.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • However, the OP did explicitly say: "I am trying to avoid converting that to .x .y and .z". Since `TVector3i` is an array, the Pascal code is going to use indexes to access the values. Changing to an `x/y/z` struct means re-writing the code logic, not just porting it to a different language. – Remy Lebeau Jul 23 '15 at 19:27
  • Hi, I have edited my question at the bottom to try and explain why im trying to avoid classes :D (and why the example uses float of int) – D-Bennett Jul 23 '15 at 19:32
  • 2
    This isn't a class. It's a struct. If you want an `[]` operator, add one. I don't think that you understand the implication of switching from a value type to a reference type. Wait until you use the `=` operator. Anyway, you've decided that you don't like this approach, so that's fine. You've already accepted an answer before having this discussion. Good luck. – David Heffernan Jul 23 '15 at 19:45
  • Hi, this was the approach I had in mind originally, and was trying to avoid it if possible, but thanks for the suggestion :) what's the issue with = operator? – D-Bennett Jul 23 '15 at 19:56
  • I explain it in my first paragraph. Do you know the difference between reference and value types? – David Heffernan Jul 23 '15 at 19:59
  • In C# or pascal? I think I understand, is Reference a pointer to an object and value is just the value right? – D-Bennett Jul 23 '15 at 20:01
  • 1
    The important think is what happens to `=`. Does it copy the value or a reference to the same object. – David Heffernan Jul 23 '15 at 20:05
  • 2
    The Delphi code you have uses values types. If you switch to a reference type (the array is a reference type), then the semantics of your code will change immeasurably. The way to achieve a verbatim port is to declare the struct as I did, and then add an indexer. – David Heffernan Jul 23 '15 at 20:08
  • @D-Bennett, if performance is important, the value type is the way to go. – LU RD Jul 23 '15 at 20:18
  • @LURD I'd say that the semantics are the important thing. Asker wants to port across lots of Delphi code as quickly as possible. Very hard to do that quickly, or indeed safely, if you switch from value type to reference type. – David Heffernan Jul 23 '15 at 20:29
  • How does variable.x == 1 differ from variable[0] == 1, I understand variable == variable will compare with references, but that is not used in the code. – D-Bennett Jul 23 '15 at 20:31
  • I'm talking about assignment, `=`. Anyway, you closed out the question. – David Heffernan Jul 23 '15 at 20:48