将TArray <X>类型转换为X数组是否安全?

Dav*_*nan 16 delphi generics casting dynamic-arrays delphi-xe2

今天我发现了一个编译器错误(QC#108577).

以下程序无法编译:

program Project1;
{$APPTYPE CONSOLE}

procedure P(M: TArray<TArray<Integer>>);
begin
  SetLength(M, 1, 2);
end;

begin
end.
Run Code Online (Sandbox Code Playgroud)

编译器在线上噱头SetLength说:

[dcc32 Error] E2029 ')' expected but ',' found
Run Code Online (Sandbox Code Playgroud)

我知道我可以像这样解决它:

procedure P(M: TArray<TArray<Integer>>);
var
  i: Integer;
begin
  SetLength(M, 1);
  for i := low(M) to high(M) do
    SetLength(M[i], 2);
end;
Run Code Online (Sandbox Code Playgroud)

但我自然希望避免不得不诉诸于此.

以下变体编译并且似乎有效:

procedure P(M: TArray<TArray<Integer>>);
type
  TArrayOfArrayOfInteger = array of array of Integer;
begin
  SetLength(TArrayOfArrayOfInteger(M), 1, 2);
end;
Run Code Online (Sandbox Code Playgroud)

我对动态数组,TArray<T>转换,引用计数等的实现细节知之甚少,以确信这是安全的.

是否有人知道这样或那样的方式是否会在运行时产生正确的代码?

Ser*_*yuz 18

编译器内部过程SetLength在堆栈上构建一个维度数组,并调用DynArraySetLength任何动态数组,无论是否通用.如果通用数组在结构上与常规动态数组不兼容,则可能不会调用用于设置长度的相同实现.

事实上文档DynArraySetLength报价SetLength为多维阵列的替代方案.DynArraySetLength也可以用来代替类型转换,但我认为没有理由偏好其中一个.