arraysdelphirecord

Defining records in Delphi - (Record as type vs Record as variable) - Differences, cons and pros..?


I've been doing some research over records in Delphi, and in most cases I see them used as Type, and then declared a new variable of it, such as:

type
  TMyRecord = record
    data1: sometype;
    data2: sometype;
  end;

var
  OnesRecord: TMyRecord;

For arrays, it's also used as:

type
  TMyRecord = record
    data1: sometype;
    data2: sometype;
  end;

var
  OnesRecord: array of TMyRecord;

My questions are the following:

Why one shouldn't use the first approach for arrays, in a way as:

type
  TMyRecord = array of record
    data1: sometype;
    data2: sometype;
  end;

var
  OnesRecord: TMyRecord;

Also, what would be the difference if one would use records defined directly as variables, such as:

var
  OnesRecord: record
    data1: sometype;
    data2: sometype;
  end;

or

var
  OnesRecord: array of record
    data1: sometype;
    data2: sometype;
  end;

?

One final thing; if one would merge the second and third approach, and have type of array, and variable of array of that type, would it be any different than having array of array?

So, is this:

type
  TMyRecord = array of record
    data1: sometype;
    data2: sometype;
  end;

var
  OnesRecord: array of TMyRecord;

any different than this:

type
  TMyRecord = record
    data1: sometype;
    data2: sometype;
  end;

var
  OnesRecord: array of array of TMyRecord;

Solution

  • There's nothing wrong doing what you're doing, just like there's nothing keeping you from overloading the Add() operator to do multiplication.

    Your questions are entirely theoretical, and so it's hard to say anything one way or another. Yes, the constructs are "legal". So what?

    It's like asking about walking on your hands vs. walking on your feet after you've discovered that you CAN walk on your hands.

    The question in all cases is the same ... why would you want to do it?

    Rather than asking about coding approaches that are "legal" but nobody uses, why don't you try showing an example where such uses would prove to be an advantage?

    From a theoretical standpoint, you're trying to mash-up two different data aggregation mechanisms.

    Arrays are a way of collecting items of the same type. Records and classes are a way of collecting related items of different types. They're both containers of sorts, but they have distinct qualities.

    You usually declare an array as array of <type> not array of record ... end.

    By convention, you define the record as a TYPE so you can "re-use" that type.

    You obviously haven't got much experience with this, because you can't actually USE these constructs outside of a very narrow setting.

    Let's say you want to define something like array of integer; you can define it as a specific type:

    type
     TIntArray = array of integer;
    

    Why would you do this? Because at times you'll discover that declaring two different things both as array of integer makes them not type-compatible, which is counter-intuitive.

    But if they're each declared as TIntArray, the compiler accepts that.

    I don't know if this is the correct terminology or not, but as far as the compiler is concerned, there IS a difference between
    myvar : <type-name> and myvar : <type-expression>.

    In this case, <type-name> would be TIntArray, and
    <type-expression> would be array of integer.

    var
      myvar1 : array of integer;
      myvar2 : TIntArray;
    

    These two are NOT type compatible in all cases. Furthermore,

    procedure myproc( AVar : array of integer )
    

    will not accept myproc(myvar2) because myvar2 is not of type
    array of integer. Really! It's of type TIntArray. See the difference?

    Now replace that declaration with any sort of record ... end, or even your array of record ... end thingie and you start to see the limitations of what you're asking. Yes, the compiler digests it just fine. It just won't let you pass anything in as an argument that matches that type! Even if they "look" exactly the same, believe it or not.

    So, to answer your own question, I challenge you to construct a non-trivial example where the things you propose actually make sense and the compiler accepts them. Because while the compiler might accept the isolated examples you've created above, they're not likely to work very well in practice (if at all).

    But you get an 'A' for Audacity in asking an insightful question!