Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the reasons to use TArray<T> instead of Array of T?

I'm migrating a legacy Delphi application to Delphi-XE2, and I'm wondering if there's a good reason to replace the arrays defined as Array of MyType to TArray<MyType>. So the question is what are the pros and cons of TArray<T> usage instead of Array of MyType?

like image 517
Salvador Avatar asked Jan 17 '13 16:01

Salvador


3 Answers

The main advantage is less onerous type identity rules. Consider:

a: array of Integer;
b: array of Integer;

These two variables are not assignment compatible. It is a compiler error to write:

a := b;

On the other hand if you use the generic syntax:

a: TArray<Integer>;
b: TArray<Integer>;

then these two variables are assignment compatible.

Sure, you can write

type
  TIntegerArray = array of Integer;

But all parties need to agree on the same type. It's fine if all code is in your control, but when using code from a variety of sources, the advent of generic dynamic arrays makes a huge difference.

The other advantage that springs to mind, in similar vein, is that you can readily use the generic array type as the return type of a generic method.

Without the generic array you are compelled to declare a type of this form:

TArrayOfT = array of T

in your generic class, which is rather messy. And if you are writing a generic method in a non-generic class, then you've no way to make that declaration. Again the generic array solves the problem.

TMyClass = class
  class function Foo<T>: TArray<T>; static;
end;

This all follows on from type compatibility rules described in the documentation like this:

Type Compatibility

Two non-instantiated generics are considered assignment compatible only if they are identical or are aliases to a common type.

Two instantiated generics are considered assignment compatible if the base types are identical (or are aliases to a common type) and the type arguments are identical.

like image 125
David Heffernan Avatar answered Nov 01 '22 07:11

David Heffernan


You can initialize TArray<T> with values with one construct:

var
  LArray: TArray<Integer>;
begin
  LArray := TArray<Integer>.Create(1, 2, 3, 4);

For array of Integer you would need to write much more code:

var
  LArray: array of Integer;
begin
  SetLength(LArray, 4);
  LArray[0] := 1;
  LArray[1] := 2;
  LArray[2] := 3;
  LArray[3] := 4;
like image 23
Linas Avatar answered Nov 01 '22 07:11

Linas


It comes in handy for function results.

Example:

The following is not allowed in Delphi. You need to declare a separate type here. What a waste of time.

function MyFunc:array of integer; 
begin
end;

Wait, generics to the resque:

function MyFunc:TArray<integer>;
begin
end;
like image 5
Wouter van Nifterick Avatar answered Nov 01 '22 09:11

Wouter van Nifterick