【问题标题】:How to work with Generic methods and parameter array of array of < T >?如何使用 <T> 数组的泛型方法和参数数组?
【发布时间】:2018-06-22 13:05:41
【问题描述】:

在使用泛型数组时,很多时候我需要知道我正在使用的数组的最大长度。很长一段时间我都在使用:

MaxIntValue([Length(Array1), Length(Array2) , Length(Array3)]); // from Math unit

然后我用我的方法简化了这个(跳过输入 Length()):

// array of array of TCardBrand
function GetMaxLength(const aArrays: array of TArrayOfCarBrand): integer;

效果很好,但现在我想创建一个通用的 MaxLength,但我无法使用它

class function MaxLength<T>(aArrays: array of array of T): integer; - it gives error: [dcc32 Error] Unit2.pas(31): E2029 Identifier expected but 'ARRAY' found

这是我正在测试的代码,其中包含来自 Math 单元的 MaxIntValue 工作示例和我的方法示例,但扩展通用 TArray 不起作用:

TCarBrand = record
    BrandID: integer;
    BrandName: string;
    BrandCountry: string;
  end;

  TArrayOfCarBrand = array of TCarBrand;

  TArray = class(System.Generics.Collections.TArray)
  public          
      // ERROR:  E2029 Identifier expected but 'ARRAY' found
       class function MaxLength<T>(aArrays: array of array of T): integer;
  end;

var  
  vCarsUS, vCarsEU, vCarsJP: TArrayOfCarBrand;

implementation

{$R *.dfm}


class function TArray.MaxLength<T>(aArrays: array of array of T): integer;
var
  i: Integer;
begin
  Result := 0;
  for i := Low(aArrays) to High(aArrays) do
    Result := MaxIntValue([Result, Length(aArrays[i])]);
end;


function GetMaxLength(const aArrays: array of TArrayOfCarBrand): integer;
var
  i: Integer;
begin
  Result := 0;
  for i := Low(aArrays) to High(aArrays) do
    Result := MaxIntValue([Result, Length(aArrays[i])]);
end;


procedure TForm2.Button1Click(Sender: TObject);
var vMaxLength: integer;
begin
  // test lengths
  SetLength(vCarsUS,1);
  SetLength(vCarsEU,10);
  SetLength(vCarsJP,100);

  // using MaxIntValue from Math unit - works OK
  vMaxLength := MaxIntValue([Length(vCarsUS), Length(vCarsEU), Length(vCarsJP)]);

  // using my method GetMaxLength - works OK
  vMaxLength := GetMaxLength([vCarsUS, vCarsEU, vCarsJP]);

  // trying to set Generic TArray.MaxLength - ERROR
  vMaxLength := TArray.MaxLength<TCarBrand>([vCarsUS, vCarsEU, vCarsJP]);
end;

如何扩展通用 MaxValue 以接受 数组的开放数组?

【问题讨论】:

  • 我能问一下为什么你坚持使用动态数组而不是集合类吗?您似乎一直处于一种不必要的复杂状态。
  • 我确实研究过一次,我使用的数组太多以至于只是一个简单的定义更改,例如从 array of T 更改为 TArray&lt;T&gt;,这几乎完成了。

标签: delphi generics delphi-10.1-berlin


【解决方案1】:

这很简单。您的函数不接受泛型数组,因为参数列表不会尝试这样做。改成这样。

class function MaxLength<T>(const aArrays: array of TArray<T>): Integer;

这里的关键是独占使用TArray&lt;T&gt;。这是通用的动态数组类型,使用它可以提供比array of 动态数组类型更灵活的类型兼容性。此处详细介绍了这些问题:What are the reasons to use TArray instead of Array of T?

这样做的结果是您需要替换所有动态类型声明并改用TArray&lt;T&gt;。事实上,您根本不需要声明任何动态数组类型。您可以删除此表单的所有声明:

type
  TFooArray = array of TFoo;

然后将所有出现的TFooArray 替换为TArray&lt;TFoo&gt;。一个附带的好处是您不需要声明任何数组类型,并且您的代码变得不那么冗长。

我还要评论说,当您只有两个参数时,使用 MaxIntValue 毫无意义。然后使用Max 函数。

【讨论】:

  • 这很好用!现在我可以传递 1-n 个数组(只要它们是 TArray)并且将获得 Max Length 值。我有时也会感到困惑,我需要LengthHigh 值吗,现在有了这个函数就不会混淆了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多