Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在delphi中如何在一个容器中存储不同的方法指针?_Delphi - Fatal编程技术网

在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作为一个开放源码。除非我找到一种方法使它们都成为一种形式,否则我无法将它们全部存储起来。你也回答了。非常感谢你的回答。开头的第一句话回答了问题。除非我找到一种方法使它们都成为一种形式,否则我无法将它们全部存储起来。你也回答了。非常感谢你的回答。