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;
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With