用TArray <xxx> </xxx>替换XXX数组是否安全

时间:2014-04-29 20:00:15

标签: arrays delphi generics delphi-xe5 dynamic-arrays

我有很多变量声明为

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

将它们替换为安全的范围:

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

2 个答案:

答案 0 :(得分:12)

正如已经回答的那样,TArray<XXX>与定义为array of XXX的任何其他自定义类型完全相同。实际上,TArray<XXX> 定义为array of XXX的自定义类型。

也就是说,在过程或函数参数的上下文中,定义为array of XXX的自定义类型等同于array of XXX。在procedure Foo(x: array of Integer)中,xopen array parameter,可以接受任何类型的整数数组。相比之下,procedure Foo(x: TArray<Integer>)仅采用实际TArray<Integer>类型。尝试传递固定大小的数组时,以及尝试传递TDynIntegerArray(另一种类型,也定义为array of Integer)时,您可以看到区别。

因此,对于变量,当然,如果您有array of XXX,请将其更改为TArray<XXX>您想要的所有内容。请确保您不进行全局搜索和替换。

答案 1 :(得分:5)

这样做非常安全。编译器将生成相同的输出。

我个人愿意,在其他条件相同的情况下,建议这样做。通用数组TArray<T>的使用为您提供了更大的灵活性和更好的类型兼容性。

当然,只有使用更实际的代码才能看到这些好处。您最常见的是使用通用容器时的好处。但是,在尝试使用多个不同的库构建代码时,您可能也会看到好处。

使用通用数组可以轻松实现类型兼容性。在通用数组之前,您将定义如下数组类型:

TIntArray = array of Integer;

如果两个库执行此操作,那么您将拥有不兼容的类型。如果库同意使用通用数组,那么将具有兼容性。

为了更清楚地看到这一点,请考虑以下片段:

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

此分配无效,并且因类型不匹配编译器错误而失败。这完全是在Pascal语言中预期的。它毕竟是强类型的,这些是不同的类型。即使它们的实现方式相同。

另一方面:

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

有效并且编译。 documentation for generic type compatibility说:

  

如果基类型相同(或者是常见类型的别名)并且类型参数相同,则两个实例化泛型被认为是赋值兼容的。