与问题TVirtualMethodInterceptor.Create doesn't support the class that has overload virtual method.相关。在修改RRUZ的答案后,我又遇到了另一个问题。 我应该如何调用第二个重载方法“SaveLog(str:string; Args:TConst数组);” 。 如下代码
type
TConst = array of TVarRec;
TLog = class
public
constructor Create();
procedure SaveLog(str: string); overload; virtual;
procedure SaveLog(str: string; Args: TConst); overload; virtual;
end;
constructor TLog.Create(str: string);
begin
end;
procedure TLog.SaveLog(str: string);
begin
MessageBox(GetFocus(), PChar(str), 'Test Message', MB_OK);
end;
procedure TLog.SaveLog(str: string; Args: TConst);
var
buf: string;
begin
buf:=Format(str, Args);
SaveLog(buf);
end;
procedure MyTest(nID: Integer);
var
ttt: TLog;
vmi: TVirtualMethodInterceptor;
begin
ttt:=TLog.Create();
try
ttt.SaveLog('ID = %d', [nID]);
vmi:=TVirtualMethodInterceptor.Create(ttt.ClassType);
try
//
finally
vmi.Free();
end;
finally
ttt.Free();
end;
end;
代码“ttt.SaveLog('ID =%d',[nID]);”将获得 编译器错误:E2250没有可以使用这些参数调用的'SaveLog'的重载版本。 我该怎么办?
答案 0 :(得分:1)
Args
参数是动态数组。创建并填充动态数组并传递它。
您的代码无法编译,因为您尝试传递打开的数组构造函数。如果你有一个开放阵列,这将是有效的,但你不是。你有一个动态数组。
您可能使用的一个有用技巧是定义一个接受变量开放数组并返回动态数组的函数。然后你可以将一个内联到另一个内联。该函数将声明如下:
function VariantOpenArrayToDynArray(const Args: array of const): TArray<TVarRec>;
请注意,我更喜欢使用通用动态数组TArray<T>
而不是TConst
。这样做有更好的类型兼容性的好处。
尽管如此,TVarRec
并非专为明确使用而设计。它是变体开放数组的运行时支持。正如Rudy的文章所示,一旦你离开编译器支持变体开放数组的安全范围,它需要一些明确的内存管理。我不建议使用TArray<TVarRec>
。
相反,我建议你使用现代变体类型,这种类型是为新式RTTI设计的。那是TValue
。此变体类型专为显式使用而设计,并自动执行内存管理。使用TArray<TValue>
而不是TArray<TVarRec>
。