任何有效的方法将TArray 转换为TStringDynArray?(Any efficient way to convert TArray to TStringDynArray?)

我的代码中很大一部分( delphi-dutil等)使用TStringDynArray 。 现在我想将TDictionary<string, string>所有键转换为TStringDynArray 。 不幸的是我只找到TDictionary.Keys.ToArray ,它是TArray<T> 。

我知道我可以写一个简单的拷贝函数来做一个原始内容拷贝,但是我的TStringDynArray通常非常大(大约10000条),所以我正在寻找一种将TArray<string>转换为TStringDynArray的有效方法。

function ConvertToStringDynArray(const A: TArray<string>): TStringDynArray; var I: Integer; begin assert(A <> nil); SetLength(Result, Length(A)); for I := 0 to Length(A) - 1 do Result[I] := A[I]; end;

Quite a big portion of my code (delphi-dutil, etc.) uses TStringDynArray. Now I want to convert all keys a TDictionary<string, string> to a TStringDynArray. Unfortunately I only found TDictionary.Keys.ToArray, which is TArray<T>.

I know I can write a simple copy function to do a raw content copy, but my TStringDynArray is usually very big (roughly 10000 entries), so I am looking for an efficient way to convert TArray<string> to TStringDynArray.

function ConvertToStringDynArray(const A: TArray<string>): TStringDynArray; var I: Integer; begin assert(A <> nil); SetLength(Result, Length(A)); for I := 0 to Length(A) - 1 do Result[I] := A[I]; end;

最满意答案

最好的解决方案是将您的代码库中的所有动态数组转换为TArray<T> 。 这是最好的,因为泛型类型具有不太严格的类型兼容性规则。 所以我建议你考虑跨代码库采取这一步骤。

但是,这仅在您控制的代码中可行。 当与代码和库进行连接时,您无法修改您的问题。

所有这些类型的根源都是动态数组,并且共享一个单一的通用实现。 这意味着堵塞是在语言层面而不是实施。 因此,可以安全地使用强制转换来使编译器接受您的分配。

var DynArr: TStringDynArray; GenericArr: TArray<string>; .... DynArr := TStringDynArray(GenericArr); GenericArr := TArray<string>(DynArr);

您可以在函数调用参数中使用这些强制转换。

因为你压制了类型检查,所以你真的不想把这些强制类型转移到你的代码中。 将它们集中到辅助函数中。 例如:

function StringDynArray(const arr: TArray<string>): TStringDynArray; begin Result := TStringDynArray(arr); end;

最后一点评论:这个相关的问题可能是有趣的: 将TArray <X>类型转换为X数组是否安全?

The best solution is to convert all dynamic arrays in your codebase to be TArray<T>. This is best because generic types have much less stringent type compatibility rules. So I suggest that you consider taking this step across your codebase.

However, that's only viable in the code that you control. When interfacing with code and libraries that you cannot modify you have a problem.

At the root of all this, all these types are dynamic arrays and share a single, common, implementation. This means that the blockage is at the language level rather than implementation. So a cast can be used, safely, to make the compiler accept you assignments.

var DynArr: TStringDynArray; GenericArr: TArray<string>; .... DynArr := TStringDynArray(GenericArr); GenericArr := TArray<string>(DynArr);

You can use these casts in function call arguments.

Because you are suppressing type checking, you really don't want to scatter these casts all over your code. Centralise them into helper functions. For instance:

function StringDynArray(const arr: TArray<string>): TStringDynArray; begin Result := TStringDynArray(arr); end;

One final comment: this related question may be of interest: Is it safe to type-cast TArray<X> to array of X?

更多推荐