Question

I have quite a few variables declared as

var
  Something: array of XXX;
begin
  SetLength(Something, 10);
  try
    ...
  finally
    SetLength(Something, 0);
  end;
end;

To what extend is safe to have them replaced:

var
  Something: TArray<XXX>;
begin
  SetLength(Something, 10);
  try
    ...
  finally
    SetLength(Something, 0);
  end;
end;
Was it helpful?

Solution

As already answered, TArray<XXX> is exactly like any other custom type defined as array of XXX. In fact, TArray<XXX> is a custom type defined as array of XXX.

That said, a custom type defined as array of XXX is not equivalent to array of XXX in the context of a procedure or function parameter. In procedure Foo(x: array of Integer), x is an open array parameter, which can accept any type of integer array. In contrast, procedure Foo(x: TArray<Integer>) takes an actual TArray<Integer> type only. You can see the difference when attempting to pass a fixed-size array, but also when attempting to pass a TDynIntegerArray (a different type, also defined as array of Integer).

So, for variables, sure, if you have array of XXX, change it to TArray<XXX> all you want. Just make sure you don't do a global search and replace.

OTHER TIPS

It is perfectly safe to do this. The compiler will produce identical output.

I personally would, all other things being equal, recommend doing so. The use of the generic array TArray<T> gives you much more flexibility and better type compatibility.

Of course those benefits can only be seen with more realistic code that does some work. You most typically see benefits when using generic containers. But you might also see benefits when trying to build code using multiple different libraries.

The use of generic arrays allows easy type compatibility. Before generic arrays you would define an array type like this:

TIntArray = array of Integer;

If two libraries do this then you have incompatible types. If the libraries agree to use generic arrays then there will be compatibility.

To see this more clearly, consider this fragment:

type
  TIntArray1 = array of Integer;
  TIntArray2 = array of Integer;
....
var
  arr1: TIntArray1;
  arr2: TIntArray2;
....
arr1 := arr2;

This assignment is not valid and fails with a type mis-match compiler error. This is entirely to be expected within the Pascal language. It is after all strongly typed and these are distinct types. Even if they are implemented identically.

On the other hand:

var
  arr1: TArray<Integer>;
  arr2: TArray<Integer>;
....
arr1 := arr2;

is valid and does compile. The documentation for generic type compatibility says:

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top