Вам придется связать имя или индекс с ними другими способами. Анонимные методы не имеют имен и могут фиксировать состояние (поэтому они воссоздаются для каждого экземпляра); нет простого способа сделать их сопоставимыми, не нарушая инкапсуляцию.
Вы можете получить объект за ссылкой на метод, если за ним действительно стоит объект (нет никакой гарантии - интерфейсы, на которые ссылаются методы, реализованы в терминах семантики COM, все, что им действительно нужно, это COM vtable ):
function Intf2Obj(x: IInterface): TObject;
type
TStub = array[0..3] of Byte;
const
// ADD [ESP+$04], imm8; [ESP+$04] in stdcall is Self argument, after return address
add_esp_04_imm8: TStub = ($83, $44, $24, $04);
// ADD [ESP+$04], imm32
add_esp_04_imm32: TStub = ($81, $44, $24, $04);
function Match(L, R: PByte): Boolean;
var
i: Integer;
begin
for i := 0 to SizeOf(TStub) - 1 do
if L[i] <> R[i] then
Exit(False);
Result := True;
end;
var
p: PByte;
begin
p := PPointer(x)^; // get to vtable
p := PPointer(p)^; // load QueryInterface stub address from vtable
if Match(p, @add_esp_04_imm8) then
begin
Inc(p, SizeOf(TStub));
Result := TObject(PByte(Pointer(x)) + PShortint(p)^);
end
else if Match(p, @add_esp_04_imm32) then
begin
Inc(p, SizeOf(TStub));
Result := TObject(PByte(Pointer(x)) + PLongint(p)^);
end
else
raise Exception.Create('Not a Delphi interface implementation?');
end;
type
TAction = reference to procedure;
procedure Go;
var
a: TAction;
i: IInterface;
o: TObject;
begin
a := procedure
begin
Writeln('Hey.');
end;
i := PUnknown(@a)^;
o := i as TObject; // Requires Delphi 2010
o := Intf2Obj(i); // Workaround for non-D2010
Writeln(o.ClassName);
end;
begin
Go;
end.
Это будет (в настоящее время) печатать Go$0$ActRec
; но если у вас есть второй анонимный метод, структурно идентичный, он приведет ко второму методу, потому что тела анонимного метода не сравниваются на структурное равенство (это будет дорогостоящая, низкозатратная оптимизация, так как программист вряд ли будет делать такие вещи, и крупные структурные сравнения не дешево).
Если бы вы использовали более позднюю версию Delphi, вы могли бы использовать RTTI для класса этого объекта и попытаться сравнить поля и самостоятельно выполнить структурное сравнение.