gpt4 book ai didi

delphi - delphi 如何在一个容器中存储不同的方法指针?

转载 作者:行者123 更新时间:2023-12-03 19:06:32 25 4
gpt4 key购买 nike

我有以下方法指针

type
TMethod1 = procedure(aValue: TType1) of object;
TMethod2 = procedure(aValue: TType2) of object;
.
.
TMethodN = procedure(aValue: TTypeN) of object;

我想将它们存放在一个容器中。

我找到了 this answer ,其中指向 TMethod1 的指针用于存储一个方法,然后调用它。但是,出于以下原因,我宁愿不使用它:
  • 它分配新的内存块,然后我应该决定何时释放它(从未将它从一 block 区域中取出)。
  • 它假设所有方法都具有相同的定义,这不是我的情况。
  • 这是一种方法。我有一个数组,我不知道我将如何维护这样的存储。

  • the documentation 中有一个例子它使用 TMethod 方法,但是以不同的方式,不再需要上面的第二个假设。在调用该方法的最后一步中,我必须进行不安全的类型转换,这也是我想远离的事情。

    我该如何做到这一点?

    澄清 关于我将如何使用这些方法:

    我有一个
    procedure DoWork(aData: TType1; method: TMethod1);
    begin
    store aData in a field;
    store method in my container;
    end;

    然后,处理 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);

    ...

    另一种解决方案是完全不依赖特定类型,只为容器定义一种方法类型。让 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);

    ...

    关于delphi - delphi 如何在一个容器中存储不同的方法指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47294601/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com