Проблема с Typecast в Delphi XE - PullRequest
       54

Проблема с Typecast в Delphi XE

2 голосов
/ 15 сентября 2011

Я пытаюсь сделать список процедур следующим образом:

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.

Ответы [ 2 ]

5 голосов
/ 15 сентября 2011

Типовое преобразование недопустимо, поскольку вы не можете поместить указатель метода на указатель. Указатель метода на самом деле представляет собой два указателя, первый из которых является адресом метода, а второй - ссылкой на объект, которому принадлежит метод.См. Процедурные типы в документации.Это не будет работать ни в одной версии Delphi.

4 голосов
/ 15 сентября 2011

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;

Отказ от ответственности: полностью непроверенный код, используйте на свой страх и риск.

...