2011-09-15 137 views
2

类型转换我尝试做的程序列表中这样说:
问题与德尔福XE

type 

TProc = procedure of object; 

TMyClass=class 
private 
fList:Tlist; 
function getItem(index:integer):TProc; 
{....} 
public 
{....} 
end; 
implementation 
{....} 
function TMyClass.getItem(index: Integer): TProc; 
begin 
Result:= TProc(flist[index]);// <--- error is here! 
end; 
{....} 
end. 

,并得到错误:

E2089 Invalid typecast

我怎样才能解决这个问题? 正如我所看到的,我只能通过一个属性Proc:TProc;制作假类并列出它。但我觉得这是一种糟糕的方式,不是吗?

PS:项目必须与delphi-7兼容。

+1

如果您希望代码在D7中工作,您为什么使用XE?那会导致你的悲伤。 –

回答

5

该类型转换是无效的,因为您不能适应方法指针指向一个指针,方法指针实际上是两个指针,第一个是方法的地址,第二个方法是对该方法所属对象的引用。请参阅文档中的Procedural Types。这在Delphi的任何版本中都不起作用。

+0

+1事实上,这不适用于任何版本的Delphi。 –

4

Sertac解释了为什么您的代码无法正常工作。为了在Delphi 7中实现这样的列表,你可以做这样的事情。

type 
    PProc = ^TProc; 
    TProc = procedure of object; 

    TProcList = class(TList) 
    private 
    FList: TList; 
    function GetCount: Integer; 
    function GetItem(Index: Integer): TProc; 
    procedure SetItem(Index: Integer; const Item: TProc); 
    public 
    constructor Create; 
    destructor Destroy; override; 
    property Count: Integer read GetCount; 
    property Items[Index: Integer]: TProc read GetItem write SetItem; default; 
    function Add(const Item: TProc): Integer; 
    procedure Delete(Index: Integer); 
    procedure Clear; 
    end; 

type 
    TProcListContainer = class(TList) 
    protected 
    procedure Notify(Ptr: Pointer; Action: TListNotification); override; 
    end; 

procedure TProcListContainer.Notify(Ptr: Pointer; Action: TListNotification); 
begin 
    inherited; 
    case Action of 
    lnDeleted: 
    Dispose(Ptr); 
    end; 
end; 

constructor TProcList.Create; 
begin 
    inherited; 
    FList := TProcListContainer.Create; 
end; 

destructor TProcList.Destroy; 
begin 
    FList.Free; 
    inherited; 
end; 

function TProcList.GetCount: Integer; 
begin 
    Result := FList.Count; 
end; 

function TProcList.GetItem(Index: Integer): TProc; 
begin 
    Result := PProc(FList[Index])^; 
end; 

procedure TProcList.SetItem(Index: Integer; const Item: TProc); 
var 
    P: PProc; 
begin 
    New(P); 
    P^ := Item; 
    FList[Index] := P; 
end; 

function TProcList.Add(const Item: TProc): Integer; 
var 
    P: PProc; 
begin 
    New(P); 
    P^ := Item; 
    Result := FList.Add(P); 
end; 

procedure TProcList.Delete(Index: Integer); 
begin 
    FList.Delete(Index); 
end; 

procedure TProcList.Clear; 
begin 
    FList.Clear; 
end; 

免责声明:完全未经测试的代码,使用您自己的风险。

+0

谢谢你,你的变体非常有趣。但似乎我会使用假类,因为它更适合整体概念 –