使用TArray <T>而不是T的数组的原因是什么?

Sal*_*dor 30 delphi delphi-xe2

我迁移遗留Delphi应用程序到德尔福XE2,我想知道如果有一个很好的理由,以取代定义为数组Array of MyTypeTArray<MyType>.所以问题是TArray<T>使用的优缺点是什么,而不是MyType数组?

Dav*_*nan 34

主要优点是较少繁重的类型标识规则.考虑:

a: array of Integer;
b: array of Integer;
Run Code Online (Sandbox Code Playgroud)

这两个变量不兼容.编写错误是编译错误:

a := b;
Run Code Online (Sandbox Code Playgroud)

另一方面,如果您使用通用语法:

a: TArray<Integer>;
b: TArray<Integer>;
Run Code Online (Sandbox Code Playgroud)

然后这两个变量是赋值兼容的.

当然,你可以写

type
  TIntegerArray = array of Integer;
Run Code Online (Sandbox Code Playgroud)

但所有各方都需要就同一类型达成一致.如果所有代码都在你的控制之下就没问题了,但是当使用来自各种来源的代码时,通用动态数组的出现会产生巨大的差异.

与此类似的是,您可以轻松地使用通用数组类型作为泛型方法的返回类型.

如果没有泛型数组,则必须声明此表单的类型:

TArrayOfT = array of T
Run Code Online (Sandbox Code Playgroud)

在你的泛型类中,这是相当混乱的.如果您在非泛型类中编写泛型方法,那么您无法进行该声明.通用数组再次解决了这个问题.

TMyClass = class
  class function Foo<T>: TArray<T>; static;
end;
Run Code Online (Sandbox Code Playgroud)

这一切都遵循文档中描述的类型兼容性规则,如下所示:

类型兼容性

两个非实例化的泛型只有在它们相同或者是普通类型的别名时才被认为是赋值兼容的.

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

  • @Serg:尚未修复,但不适用于此处.问题是方法多次重复,但`TArray <T>`不是类,它是一个数组.所以没有方法可以复制,因此没有代码膨胀. (7认同)
  • 我很少使用`TArray <T>`,但这可能是因为Delphi的开发人员仍然主要编写类似于1996年的代码.这是一种保守的方法,至少可以忽略新语法十年.(GRIN) (4认同)
  • @Warren我们的代码库专门用于我的答案中列出的原因.在我看来,这是一个明智的选择. (4认同)
  • 在方法中声明常量数组参数的一个重要方面是使用`AMethod(const a:array of T);`而不是`AMethod(const a:TArray <T>);`.前者接受传递任何T数组,也就是调用`AMethod([1,2,3]);`的常量表达式,而后者只接受`TArray <T>`类型的参数. (4认同)
  • 使用泛型的膨胀代码怎么样?问题是在XE2/XE3中解决了吗?我绝不会建议将变量声明为TArray <T>. (2认同)

Lin*_*nas 20

您可以TArray<T>使用一个构造初始化值:

var
  LArray: TArray<Integer>;
begin
  LArray := TArray<Integer>.Create(1, 2, 3, 4);
Run Code Online (Sandbox Code Playgroud)

因为array of Integer你需要编写更多的代码:

var
  LArray: array of Integer;
begin
  SetLength(LArray, 4);
  LArray[0] := 1;
  LArray[1] := 2;
  LArray[2] := 3;
  LArray[3] := 4;
Run Code Online (Sandbox Code Playgroud)

  • `type TMyIntArr =整数数组; var LArray:TMyIntArr; LArray:= TMyIntArr.Create(1,2,3,4);`工作正常. (12认同)
  • @LURD:+1,它适用于Delphi 2007以及支持泛型的更高版本(以及除整数以外的类型,以确保清楚). (4认同)
  • @EricGrange,你能举例说明吗?我在XE3中反汇编了泛型数组create和动态数组,编译器发出了相同的代码.对我来说没问题. (2认同)
  • @Eric:从阅读你的文章开始,我认为应该在这里澄清一点,在某些速度危急的情况下,使用Create array伪构造函数可能会降低性能.看完上面的评论后,我以为你说这是错误的.不过好文章. (2认同)

Wou*_*ick 5

它对功能结果很方便.

例:

Delphi中不允许以下内容.您需要在此声明一个单独的类型.真是浪费时间.

function MyFunc:array of integer; 
begin
end;
Run Code Online (Sandbox Code Playgroud)

等等,通知resque:

function MyFunc:TArray<integer>;
begin
end;
Run Code Online (Sandbox Code Playgroud)

  • 好吧,让我们公平,TIntegerDynArray介绍了什么?D4?D6?所以你应该使用自己定义的类型. (7认同)