【问题标题】:Problem with typecast in Delphi XEDelphi XE 中的类型转换问题
【发布时间】:2011-11-17 13:48:27
【问题描述】:

我尝试以这种方式列出程序:

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 类型转换无效

我该如何解决? 如我所见,我可以制作一个只有一个属性Proc:TProc; 的假类并列出它。但我觉得这是一个不好的方式,不是吗?

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

【问题讨论】:

  • 如果您希望代码在 D7 中工作,为什么还要使用 XE。这会让你感到悲伤。

标签: delphi delphi-7 delphi-xe


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    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;
    

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

    【讨论】:

    • 谢谢你,你的变种很有趣。但我似乎会使用 fake-class,因为它更适合整体概念
    猜你喜欢
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    • 1970-01-01
    • 2011-06-29
    • 2011-05-31
    • 1970-01-01
    相关资源
    最近更新 更多