我有以下方法指针
type
TMethod1 = procedure(aValue: TType1) of object;
TMethod2 = procedure(aValue: TType2) of object;
.
.
TMethodN = procedure(aValue: TTypeN) of object;
Run Code Online (Sandbox Code Playgroud)
我想将它们存放在一个容器中.
我找到了这个答案,其中一个指针TMethod1用于存储一个方法,然后调用它.但是,我宁愿不使用它,原因如下:
它分配了新的内存块,然后我应该决定何时释放它(从来没有将它从一个区域中取出).
它假设所有方法都有相同的定义,这不是我的情况.
这是一种方法.我有一个他们的阵列,我不知道我将如何维持这样的存储.
文档中有一个使用TMethod方法的例子,但是以不同的方式不再需要上面的第二个假设.在调用该方法的最后一步中,我必须做一个不安全的类型转换,这也是我想要远离的东西.
我该如何做到这一点?
澄清我将如何使用这些方法:
我有一个
procedure DoWork(aData: TType1; method: TMethod1);
begin
store aData in a field;
store method in my container;
end;
Run Code Online (Sandbox Code Playgroud)
然后,处理aData和调用method.
无论您在容器中存储的是什么,都必须是相同的类型.你可以用TMethod它.它是RTL提供的特殊记录类型,表示任何 of object方法指针.
困难的部分是调用存储在容器中的方法.你不能直接调用TMethod,你必须知道它指向的确切方法类型,然后将其类型转换为该类型.例如:
var
Field: TObject; // assuming TType... are class types
Container: TList<TMethod>;
procedure DoWork<T>(aData: T; method: procedure(aValue: T) of object);
var
M: TMethod;
begin
M := TMethod(method);
Field := aData;
Container.Add(M);
end;
procedure CallFieldMethod;
var
M: TMethod;
begin
M := Container[Index];
if Field.ClassType = TType1 then
begin
TMethod1(M)(TType1(Field));
end
else if Field.ClassType = TType2 then
begin
TMethod2(M)(TType2(Field));
end
...
end;
...
procedure TSomeClass.MethodForType1(aValue: TType1);
begin
// use aValue as needed...
end;
DoWork<TType1>(Type1Obj, MethodForType1);
...
procedure TSomeClass.MethodForType2(aValue: TType2);
begin
// use aValue as needed...
end;
DoWork<TType2>(Type2Obj, MethodForType2);
...
Run Code Online (Sandbox Code Playgroud)
另一种解决方案是完全不依赖于特定类型,只需为容器定义1种方法类型.让来电者DoWork()决定做什么:
type
TMyMethod = procedure(aValue: Pointer) of object;
var
Field: Pointer;
Container: TList<TMyMethod>;
procedure DoWork(aData: Pointer; method: TMyMethod);
begin
Field := aData;
Container.Add(method);
end;
procedure CallFieldMethod;
begin
Container[Index](Field);
end;
...
procedure TSomeClass.MethodForType1(aValue: Pointer);
begin
// use TType1(aValue) as needed...
end;
DoWork(Type1Obj, MethodForType1);
...
procedure TSomeClass.MethodForType2(aValue: Pointer);
begin
// use TType2(aValue) as needed...
end;
DoWork(Type2Obj, MethodForType2);
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |