DiG*_*iGi 11 delphi oop interface callback
是否可以将接口的方法作为参数传递?
我正在尝试这样的事情:
interface
type
TMoveProc = procedure of object;
// also tested with TMoveProc = procedure;
// procedure of interface is not working ;)
ISomeInterface = interface
procedure Pred;
procedure Next;
end;
TSomeObject = class(TObject)
public
procedure Move(MoveProc: TMoveProc);
end;
implementation
procedure TSomeObject.Move(MoveProc: TMoveProc);
begin
while True do
begin
// Some common code that works for both procedures
MoveProc;
// More code...
end;
end;
procedure Usage;
var
o: TSomeObject;
i: ISomeInterface;
begin
o := TSomeObject.Create;
i := GetSomeInterface;
o.Move(i.Next);
// somewhere else: o.Move(i.Prev);
// tested with o.Move(@i.Next), @@... with no luck
o.Free;
end;
Run Code Online (Sandbox Code Playgroud)
但它不起作用是因为:
E2010不兼容的类型:'TMoveProc'和'过程,无类型指针或无类型参数'
当然,我可以为每个电话做私人方法,但这很难看.有没有更好的方法?
德尔福2006
编辑:我知道我可以传递整个界面,但后来我必须指定使用哪个函数.我不希望两个完全相同的程序与一个不同的调用.
我可以使用第二个参数,但这也很难看.
type
SomeInterfaceMethod = (siPred, siNext)
procedure Move(SomeInt: ISomeInterface; Direction: SomeInterfaceMethod)
begin
case Direction of:
siPred: SomeInt.Pred;
siNext: SomeInt.Next
end;
end;
Run Code Online (Sandbox Code Playgroud)
谢谢大家的帮助和想法.清洁解决方案(对于我的Delphi 2006)是Diego的访客.现在我使用简单("丑陋")包装器(我自己的,TOndrej和Aikislave的相同解决方案).
但真正的答案是"没有(直接)方式将接口的方法作为参数传递而没有某种提供者.
如果您使用的是Delphi 2009,则可以使用匿名方法执行此操作:
TSomeObject = class(TObject)
public
procedure Move(MoveProc: TProc);
end;
procedure Usage;
var
o: TSomeObject;
i: ISomeInterface;
begin
o := TSomeObject.Create;
i := GetSomeInterface;
o.Move(procedure() begin i.Next end);
Run Code Online (Sandbox Code Playgroud)
尝试将引用传递给接口方法的问题是您没有传递对接口本身的引用,因此接口无法引用计数.但是匿名方法本身就是引用计数,因此这里的匿名方法内的接口引用也可以被引用计数.这就是这种方法有效的原因.
这是在 Delphi 20006 中运行的另一个解决方案。它类似于 @Rafael 的想法,但使用接口:
interface
type
ISomeInterface = interface
//...
end;
IMoveProc = interface
procedure Move;
end;
IMoveProcPred = interface(IMoveProc)
['{4A9A14DD-ED01-4903-B625-67C36692E158}']
end;
IMoveProcNext = interface(IMoveProc)
['{D9FDDFF9-E74E-4F33-9CB7-401C51E7FF1F}']
end;
TSomeObject = class(TObject)
public
procedure Move(MoveProc: IMoveProc);
end;
TImplementation = class(TInterfacedObject,
ISomeInterface, IMoveProcNext, IMoveProcPred)
procedure IMoveProcNext.Move = Next;
procedure IMoveProcPred.Move = Pred;
procedure Pred;
procedure Next;
end;
implementation
procedure TSomeObject.Move(MoveProc: IMoveProc);
begin
while True do
begin
// Some common code that works for both procedures
MoveProc.Move;
// More code...
end;
end;
procedure Usage;
var
o: TSomeObject;
i: ISomeInterface;
begin
o := TSomeObject.Create;
i := TImplementation.Create;
o.Move(i as IMoveProcPred);
// somewhere else: o.Move(i as IMoveProcNext);
o.Free;
end;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3901 次 |
最近记录: |