在delphi中如何在一个容器中存储不同的方法指针?
我有以下方法指针在delphi中如何在一个容器中存储不同的方法指针?,delphi,Delphi,我有以下方法指针 type TMethod1 = procedure(aValue: TType1) of object; TMethod2 = procedure(aValue: TType2) of object; . . TMethodN = procedure(aValue: TTypeN) of object; 我想把它们放在一个容器里 我发现,其中一个指向TMethod1的指针用于存储一个方法,然后调用它。但是,我不想使用它,原因如下: 它分配新的内存块,然后
type
TMethod1 = procedure(aValue: TType1) of object;
TMethod2 = procedure(aValue: TType2) of object;
.
.
TMethodN = procedure(aValue: TTypeN) of object;
我想把它们放在一个容器里
我发现,其中一个指向TMethod1
的指针用于存储一个方法,然后调用它。但是,我不想使用它,原因如下:
- 它分配新的内存块,然后我应该决定什么时候释放它(从来没有一块一块地把它从那个区域释放出来)
- 它假设所有的方法都有相同的定义,这不是我的情况
- 这是一种方法。我有一个阵列,我不知道如何维护这样的存储
procedure DoWork(aData: TType1; method: TMethod1);
begin
store aData in a field;
store method in my container;
end;
然后,处理
aData
并调用方法
存储在容器中的任何内容都必须是相同的类型。您可以使用t方法
。它是RTL提供的一种特殊记录类型,用于表示对象方法指针的任何
最难的部分是调用存储在容器中的方法。您不能直接调用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);
...
容器中存储的内容必须是相同的类型。您可以使用t方法
。它是RTL提供的一种特殊记录类型,用于表示对象
方法指针的任何
最难的部分是调用存储在容器中的方法。您不能直接调用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);
...
有什么问题吗。使用t列表
。分配没有问题t方法
是一种自动存储的值类型。如果容器中有不同的类型,就是这样。这是异质的。如果类型相同,则使用TList
。前者需要施法才能召唤,而后者则不然。@DavidHeffernan我如何再次召唤他们。问题是如何知道我给他们中的哪一个打电话。您的建议在文档示例中。显然,您必须跟踪类型存储和调用之间的时间对类型有影响的部分已丢失。@nasreddineabdellahgalfout如果我理解正确,您正在尝试实现某种结构来存储将要执行的任务所需的数据将来执行。如果您是,那么您可能需要检查OmniThreadLibrary如何实现遵循这种概念的自己的任务。也许你不知道,但是PrimožGabrijelčič最近将OmniThreadLibrary作为一个开放源代码。问题是什么。使用t列表
。分配没有问题t方法
是一种自动存储的值类型。如果容器中有不同的类型,就是这样。这是异质的。如果类型相同,则使用TList
。前者需要施法才能召唤,而后者则不然。@DavidHeffernan我如何再次召唤他们。问题是如何知道我给他们中的哪一个打电话。您的建议在文档示例中。显然,您必须跟踪类型存储和调用之间的时间对类型有影响的部分已丢失。@nasreddineabdellahgalfout如果我理解正确,您正在尝试实现某种结构来存储将要执行的任务所需的数据将来执行。如果您是,那么您可能需要检查OmniThreadLibrary如何实现遵循这种概念的自己的任务。也许你不知道,但是PrimožGabrijelčič最近将OmniThreadLibrary作为一个开放源码。除非我找到一种方法使它们都成为一种形式,否则我无法将它们全部存储起来。你也回答了。非常感谢你的回答。开头的第一句话回答了问题。除非我找到一种方法使它们都成为一种形式,否则我无法将它们全部存储起来。你也回答了。非常感谢你的回答。