为什么在Delphi10中,`Explicit(array of T)`接收垃圾?

为什么在Delphi10中,`Explicit(array of T)`接收垃圾?,delphi,operator-overloading,delphi-10-seattle,Delphi,Operator Overloading,Delphi 10 Seattle,我用的是德尔福10西雅图。 当我编译这个单元时,它只是一个空白的vcl项目,带有一个按钮,该按钮已Button1Click注册。它编译并运行,但数据不是预期的。重写显式强制转换的函数Explicit将接收6109508,-1,3,而不是1,2,3。为什么会这样? 构造函数工作正常,并且具有相同的参数声明 当我使用调试器查看数据时,它是1,2,3,但当我进入显式并检查值时,它是6109508,-1,3。当值不是常量时也是如此 我使用TIntArray只是为了说明这与TGeneric具有相同的结果

我用的是德尔福10西雅图。 当我编译这个单元时,它只是一个空白的vcl项目,带有一个按钮,该按钮已Button1Click注册。它编译并运行,但数据不是预期的。重写显式强制转换的函数Explicit将接收6109508,-1,3,而不是1,2,3。为什么会这样? 构造函数工作正常,并且具有相同的参数声明

当我使用调试器查看数据时,它是1,2,3,但当我进入显式并检查值时,它是6109508,-1,3。当值不是常量时也是如此

我使用TIntArray只是为了说明这与TGeneric具有相同的结果

我错过了什么?还是这是一只虫子

unit Unit1;

interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
 TGeneric<T: record> = record
  private
    FData:  array of T;
  public
   class operator Explicit(const Values: array of T): TGeneric<T>;
   constructor Create(const Values: array of T);
 end;
   TIntArray = TGeneric<integer>;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

class operator TGeneric<T>.Explicit(const Values: array of T): TGeneric<T>;
begin
  Result :=  TGeneric<T>.Create(Values);
end;

constructor TGeneric<T>.Create(const Values: array of T);
begin
  SetLength(Self.FData, Length(Values));
   Move(Values[0], Self.FData[0], Length(Values) * SizeOf(T));
end;

procedure TForm1.Button1Click(Sender: TObject);
var a : TIntArray;
const data : array of integer = [ 1,2,3 ];
begin
  a := TGeneric<integer>.Create(data); // seems ok.
  a := TIntArray.Create(data); // seems ok.
  a := TGeneric<integer>(data); // sends garbage to Explicit.
  a := TIntArray(data); // sends garbage to Explicit.
end;

end.

此问题已在Delphi 10.2中提出并修复。如果t是托管类型,则Create将不起作用。例如,包含托管类型的记录。事实上,你自己的TGeneric就是这样一个东西。T位是整数或任何其他记录。不管理记录。它们是价值观。我们必须升级到东京,看看它是否被修复。我现在就把它关上。不是这样。如果记录包含托管类型,则对其进行管理。正如我所说,您的记录本身是受管理的,而不是受管理的。它们是值:记录是值类型,因此它们在赋值时复制、按值传递并在堆栈上分配,除非使用New和Dispose函数全局声明或显式分配。没什么可管的。但是,在创建/释放时,该记录中使用的所有托管类型都会进行引用计数。这是离题的。我没有东京,但假设这是正确的答案。