Przypisz anonimową metodę do zmiennej interfejsu lub parametru?

Anonimowe metody są zasadniczointerfaces zInvoke metoda:

type
  TProc = reference to procedure;

  IProc = interface
    procedure Invoke;
  end;

Czy istnieje możliwość przypisania ich do rzeczywistej zmiennej interfejsu lub przekazania ich jako parametru interfejsu?

procedure TakeInterface(const Value: IInterface);
begin
end;

var
  P: TProc;
  I: IInterface;
begin
  I := P; // E2010
  TakeInterface(P); // E2010
end;

[Błąd DCC32] E2010 Niekompatybilne typy: „IIpowierzchnia” i „procedura, wskaźnik bez typu lub parametr bez typu”

Pytanie: Jaki byłby przypadek użycia tego?

Istnieje wiele obiektów, których nie można po prostu utrzymać przy pomocy odniesienia do interfejsu. Dlatego są owinięci w zamknięcie i zostają z nim zniszczeni,„Inteligentne wskaźniki”:

type
  I<T> = reference to function : T;

  TInterfaced<T: class> = class (TInterfacedObject, I<T>)
  strict private
    FValue: T;
    function Invoke: T; // Result := FValue;
  public
    constructor Create(const Value: T); // FValue := Value;
    destructor Destroy; override; // FValue.Free;
  end;

  IInterfacedDictionary<TKey, TValue> = interface (I<TDictionary<TKey, TValue>>) end;

  TKey = String;
  TValue = String;

var
  Dictionary: IInterfacedDictionary<TKey, TValue>;
begin
  Dictionary := TInterfaced<TDictionary<TKey, TValue>>
    .Create(TDictionary<TKey, TValue>.Create);
  Dictionary.Add('Monday', 'Montag');
end; // FRefCount = 0, closure with object is destroyed

Czasami konieczne jest nie tylko utrzymanie przy życiu jednego obiektu, ale także kontekst z nim związany. Wyobraź sobie, że maszTDictionary<TKey, TValue> i wyciągasz z niego numerator:TEnumerator<TKey>, TEnumerator<TValue> lubTEnumerator<TPair<TKey, TValue>>. Albo słownik zawiera ijest właścicielem TObjects. Następnie zarówno nowy obiekt, jak i zamknięcie słownika wejdą do nowego zamknięcia, aby utworzyć jedno pojedyncze, samodzielne odniesienie:

type
  TInterfaced<IContext: IInterface; T: class> = class (TInterfacedObject, I<T>)
  strict private
    FContext: IContext;
    FValue: T;
    FFreeObject: Boolean;
    function Invoke: T; // Result := FValue;
  public
    constructor Create(const Context: IContext; const Value: T; const FreeObject: Boolean = True); // FValue = Value; FFreeObject := FreeObject;
    destructor Destroy; override; // if FFreeObject then FValue.Free;
  end;

  IInterfacedEnumerator<T> = interface (I<TEnumrator<T>>) end;

  TValue = TObject; // 

var
  Dictionary: IInterfacedDictionary<TKey, TValue>;
  Enumerator: IInterfacedEnumerator<TKey>;
  Obj: I<TObject>;
begin
  Dictionary := TInterfaced<TDictionary<TKey, TValue>>
    .Create(TObjectDictionary<TKey, TValue>.Create([doOwnsValues]));
  Dictionary.Add('Monday', TObject.Create);

  Enumerator := TInterfaced<
    IInterfacedDictionary<TKey, TValue>,
    TEnumerator<TKey>
  >.Create(Dictionary, Dictionary.Keys.GetEnumerator);

  Obj := TInterfaced<
    IInterfacedDictionary<TKey, TValue>,
    TObject
  >.Create(Dictionary, Dictionary['Monday'], False);

  Dictionary := nil; // closure with object still held alive by Enumerator and Obj.
end;

Teraz chodzi o stopienieTInterfaced<T> iTInterfaced<IContext, T>, co spowodowałoby, że parametr typu dla kontekstu stałby się przestarzały (wystarczy interfejs) i spowodowałoby powstanie tych konstytucji:

constructor TInterfaced<T: class>.Create(const Value: T; const FreeObject: Boolean = True); overload;
constructor TInterfaced<T: class>.Create(const Context: IInterface; const Value: T; const FreeObject: Boolean = True); overload;

Bycie (czystym) zamknięciem może nie być podstawowym zastosowaniem, które można by pomyśleć podczas pracy z anonimowymi metodami. Jednak ich typy mogą być podane jako interfejs klasy, której obiekty mogą czyścić po zniszczeniu zamknięcia, a takżeTFunc<T> sprawia, że ​​płynny dostęp do jego treści. Chociaż nie mają wspólnego przodka i wydaje się, że mają wartościreference to typów nie można przypisać do typów interfejsów, co oznacza, że ​​nie ma zunifikowanego, bezpiecznego i przyszłościowego sposobu odwoływania się do wszystkich typów zamknięć, aby utrzymać je przy życiu.

questionAnswers(2)

yourAnswerToTheQuestion