<div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Hairy Pixels <<a href="mailto:genericptr@gmail.com">genericptr@gmail.com</a>> schrieb am So., 18. Sep. 2022, 02:50:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
<br>
> On Sep 17, 2022, at 10:57 PM, Sven Barth <<a href="mailto:pascaldragon@googlemail.com" target="_blank" rel="noreferrer">pascaldragon@googlemail.com</a>> wrote:<br>
> <br>
> === code begin ===<br>
> <br>
> type<br>
> TProc = reference to procedure;<br>
> TMyClass = class<br>
> procedure DoThis;<br>
> end;<br>
> <br>
> TCapturer = class(TInterfacedObject, TProc)<br>
> m: procedure of object;<br>
> procedure Anonymous1;<br>
> <br>
> procedure TProc.Invoke = Anonymous1;<br>
> end;<br>
> <br>
> var<br>
> p: TProc;<br>
> c: TMyClass;<br>
> capturer: TCapturer;<br>
> capturer_keepalive: IUnknown;<br>
> begin<br>
> capturer := TCapturer.Create;<br>
> capturer_keepalive := capturer;<br>
> c := TMyClass.Create;<br>
> capturer.m := @c.DoThis;<br>
> p := capturer as TProc;<br>
> end.<br>
> <br>
> === code end ===<br>
<br>
Well if p is effectively TCapturer then you COULD get back TMethod from m (procedure of object) but the compiler doesn’t have a method generated for this.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">No, you can't, because if you have multiple such assignments inside one function the capture object is shared and you'd have multiple fields where you wouldn't know to which anonymous function is belongs:</div><div dir="auto"><br></div><div dir="auto">=== code begin ===</div><div dir="auto"><br></div><div dir="auto">Proc1 := @c.OnChange;</div><div dir="auto">Proc2 := @c.OnClick;</div><div dir="auto">Proc3 := @c2.OnChange;</div><div dir="auto"><br></div><div dir="auto">=== code end ===</div><div dir="auto"><br></div><div dir="auto">Will result in the following capture object:</div><div dir="auto"><br></div><div dir="auto">=== code begin ===</div><div dir="auto"><br></div><div dir="auto">type</div><div dir="auto"> TCapturer = class(TInterfacedObject, TProc1, TProc2, TProc3)</div><div dir="auto"> m1: TNotifyEvent;</div><div dir="auto"> m2: TNotifyEvent;</div><div dir="auto"> m3: TNotifyEvent;</div><div dir="auto"><br></div><div dir="auto"> procedure Anonymous1(Sender :TObject); //will call m1</div><div dir="auto"> procedure Anonymous2(Sender: TObject); // will call m2</div><div dir="auto"> procedure Anonymous3(Sender: TObject); // will call m3</div><div dir="auto"> end;</div><div dir="auto"><br></div><div dir="auto">=== code end ===</div><div dir="auto"><br></div><div dir="auto">Please note that you can't rely on the index as other converted anonymous methods (maybe with the same signature) might be intermixed. So you won't know which field is used by what method. </div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I read your announcement email again last night and saw that TProc could actually be subclassed which opens up the possibility to read the field (if it’s not intentionally hidden) or use the RTTI perhaps even. Is that possible? If the field “m" is hidden I would say that should be exposed for the purposes of subclassing .<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">When you subclass a function reference you can not assign any function to it, but you really need to use a self written class type that you use as instance. </div><div dir="auto"><br></div><div dir="auto">Regards, </div><div dir="auto">Sven </div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
</blockquote></div></div></div>