【问题标题】:Why does generic TArray Create syntax differs from other class functions?为什么泛型 TArray Create 语法与其他类函数不同?
【发布时间】:2020-03-19 07:53:51
【问题描述】:

我注意到在我看来是通用 TArray 语法不一致的地方(这让我抓狂......)

“构造函数”函数需要通过函数名之前指定类型来调用。

MyArray := TArray<Integer>.Create(3, 2, 1);

其他类函数需要在函数名之后指定类型调用

TArray.Sort<Integer>(MyArray);

他们这样做有实际原因吗?

【问题讨论】:

  • 可能是因为 TArray 不是一个类?另一方面,TArray 是一个类,它提供了一些与 TArray 实例一起使用的函数。我们不应该混合 TArray 和 TArray - 它们是完全不同的东西。
  • 第一个TArrayarray of T的系统类型定义。创建可以写成MyArray := [3,2,1]; 第二个TArray 是一个类。
  • 是的,使用Create 会使动态数组感到困惑。他们应该更好地使用New-ala C#-或Init-ala Turbo Pascal。但现在为时已晚。

标签: arrays delphi generics delphi-xe7 generic-collections


【解决方案1】:

泛型数组是这样定义的

TArray<T> = array of T;

这是动态数组的别名。动态数组有一个内在的Create 方法。甚至是非通用的。

type
  TMyDynArr = array of Integer;
....
arr := TMyDynArr.Create(0, 1, 2);

这个Create 方法是编译器固有的。注意它如何接受任意数量的参数。

另一方面,TArray 类具有其通用的Sort 方法。这是在 RTL 中实现的。请记住,TArray 永远不会被实例化,它只是泛型类方法的所在地。

我的猜测是,将方法添加到动态数组类型需要编译器支持,因为它们是内在函数。但是添加到TArray 更简单,因为它是在 RTL 层完成的,不需要编译器支持。

您无法在此处更改任何内容,因此为此烦恼无济于事。你不能改变它。习惯就好。

【讨论】:

    【解决方案2】:

    第一个TArrayarray of T 的系统类型定义。创作也可以这样写:

    MyArray := [3,2,1]; 
    

    第二个TArray 是Generics.Collections 中定义的一个类。

    他们没有任何关系。


    还要注意TArray 类使用泛型的方式称为Parameterized Methods

    Type
      TArray = class
        ...
        class procedure Sort<T>(var Values: array of T); overload; static;
        ...
      end; 
    

    这是一种减少代码重复的方法。

    【讨论】:

    • 当然,Embarcadero 可以将类型参数放在类名而不是方法上(所以你应该写成TArray&lt;Integer&gt;.Sort())。但是,这个 TArray&lt;T&gt; 类将与 TArray&lt;T&gt; = array of T 类型发生冲突。我想你可以通过为TArray&lt;T&gt; = array of T 创建一个记录助手来解决这个问题,但不幸的是,not possible
    • @AndreasRejbrand,是的,这也是一个可能的解释。如果编译器设计得更好,可以推断出类型,所以你可以写TArray.Sort(MyArray);
    猜你喜欢
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    相关资源
    最近更新 更多