如何使用 <T> 数组的泛型方法和参数数组?
How to work with Generic methods and parameter array of array of < T >?
很多时候在处理通用数组时我需要知道我正在处理的数组的最大长度。很长一段时间我都在使用:
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
这是我正在测试的代码,其中包含来自数学单元的 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 以接受 数组的开放数组?
很简单。您的函数不接受泛型数组,因为参数列表不会尝试这样做。改成这样。
class function MaxLength<T>(const aArrays: array of TArray<T>): Integer;
这里的关键是只使用TArray<T>
。这是通用动态数组类型,使用它可以提供比 array of
动态数组类型更灵活的类型兼容性。此处详细介绍了这些问题:What are the reasons to use TArray instead of Array of T?
这样做的结果是您需要替换所有动态类型声明并改用 TArray<T>
。事实上,您根本不需要声明任何动态数组类型。您可以删除所有这种形式的声明:
type
TFooArray = array of TFoo;
然后将所有出现的 TFooArray
替换为 TArray<TFoo>
。一个附带的好处是您不需要声明任何数组类型并且您的代码变得不那么冗长。
我还要评论说,当您只有两个参数时,使用 MaxIntValue
毫无意义。然后使用Max
函数。
很多时候在处理通用数组时我需要知道我正在处理的数组的最大长度。很长一段时间我都在使用:
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
这是我正在测试的代码,其中包含来自数学单元的 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 以接受
很简单。您的函数不接受泛型数组,因为参数列表不会尝试这样做。改成这样。
class function MaxLength<T>(const aArrays: array of TArray<T>): Integer;
这里的关键是只使用TArray<T>
。这是通用动态数组类型,使用它可以提供比 array of
动态数组类型更灵活的类型兼容性。此处详细介绍了这些问题:What are the reasons to use TArray instead of Array of T?
这样做的结果是您需要替换所有动态类型声明并改用 TArray<T>
。事实上,您根本不需要声明任何动态数组类型。您可以删除所有这种形式的声明:
type
TFooArray = array of TFoo;
然后将所有出现的 TFooArray
替换为 TArray<TFoo>
。一个附带的好处是您不需要声明任何数组类型并且您的代码变得不那么冗长。
我还要评论说,当您只有两个参数时,使用 MaxIntValue
毫无意义。然后使用Max
函数。