Передача метода Интерфейса как параметр

Если вам нужен только максимум, вы можете поместить каталог в словарь и отключить его, а затем сохранить максимум.

from pathlib import PurePath

max_dict = {}
for path, val in lst:
    parent = PurePath(path).parent
    max_dict[parent] = max(max_dict.get(parent, float('-inf')), val)
11
задан mghie 24 June 2014 в 18:00
поделиться

5 ответов

При использовании 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);

Проблема с попыткой передать ссылку на просто метод интерфейса состоит в том, что Вы не передаете ссылку на сам интерфейс, таким образом, интерфейс не может быть считаемой ссылкой. Но анонимные методы являются самостоятельно считаемой ссылкой, таким образом, интерфейсная ссылка в анонимном методе здесь может быть ссылкой, считаемой также. Именно поэтому этот метод работы.

6
ответ дан 3 December 2019 в 07:39
поделиться

Как насчет этого:

type
  TMoveProc = procedure(const SomeIntf: ISomeInterface);

  TSomeObject = class
  public
    procedure Move(const SomeIntf: ISomeInterface; MoveProc: TMoveProc);
  end;

procedure TSomeObject.Move(const SomeIntf: ISomeInterface; MoveProc: TMoveProc);
begin
  MoveProc(SomeIntf);
end;

procedure MoveProcNext(const SomeIntf: ISomeInterface);
begin
  SomeIntf.Next;
end;

procedure MoveProcPred(const SomeIntf: ISomeInterface);
begin
  SomeIntf.Pred;
end;

procedure Usage;
var
  SomeObj: TSomeObject;
  SomeIntf: ISomeInterface;
begin
  SomeIntf := GetSomeInterface;
  SomeObj := TSomeObject.Create;
  try
    SomeObj.Move(SomeIntf, MoveProcNext);
    SomeObj.Move(SomeIntf, MoveProcPred);
  finally
    SomeObj.Free;
  end;
end;
2
ответ дан 3 December 2019 в 07:39
поделиться

Я не знаю точную причину, почему необходимо сделать это, но, лично, я думаю, что было бы лучше передать целый объект "Двигателя" вместо одного из его методов. Я использовал этот подход в прошлом, это называют шаблоном "Посетителя". tiOPF, объектная платформа персистентности, использует его экстенсивно и дает Вам хороший пример того, как это работает: Шаблон "посетитель" и tiOPF.

Это относительно длинно, но это оказалось очень полезным для меня, даже когда я не использовал tiOPF. Отметьте шаг 3 в документе, названном "Шаг № 3. Вместо того, чтобы передать указатель метода, мы передадим объект".

DiGi, для ответа на комментарий: Если Вы используете Шаблон "посетитель", то у Вас нет интерфейса, реализовывая несколько методов, но просто каждый (Выполняется). Затем у Вас был бы класс для каждого действия, как TPred, TNext, TSomething, и Вы передаете экземпляр таких классов к объекту, который будет обработан. Таким способом Вы не должны знать, что звонить, Вы просто звоните "Посетителю. Выполнитесь", и это сделает задание.

Здесь можно найти основной пример:

interface

type
TVisited = class;

TVisitor = class
  procedure Execute(Visited: TVisited); virtual; abstract;
end;

TNext = class(TVisitor)
  procedure Execute (Visited: TVisited); override;
end;

TPred = class(TVisitor)
  procedure Execute (Visited: TVisited); override;
end;

TVisited = class(TPersistent)
public
  procedure Iterate(pVisitor: TVisitor); virtual;
end;

implementation

procedure TVisited.Iterate(pVisitor: TVisitor);
begin
  pVisitor.Execute(self);
end;

procedure TNext.Execute(Visited: TVisited);
begin
  // Implement action "NEXT"
end; 

procedure TPred.Execute(Visited: TVisited);
begin
  // Implement action "PRED"
end;

procedure Usage;
var
  Visited: TVisited;
  Visitor: TVisitor;
begin
  Visited := TVisited.Create;
  Visitor := TNext.Create;

  Visited.Iterate(Visitor);
  Visited.Free;
end;
4
ответ дан 3 December 2019 в 07:39
поделиться

Вам в настоящее время определяли TMoveProc как

TMoveProc = procedure of object;

Испытайте взятие "объекта", который подразумевает скрытое "этот" указатель как первый параметр.

TMoveProc = procedure;

Это должно позволить нормальной процедуре быть названной.

-1
ответ дан 3 December 2019 в 07:39
поделиться

Вы не можете. Из-за обзора Интерфейсов это было бы возможно (возможно?), чтобы Интерфейс был выпущен, прежде чем Вы вызвали.Next функцию. Если Вы хотите сделать это, необходимо передать целый интерфейс методу, а не просто методу.

Отредактированный... Извините, этот следующий бит, конкретно "Интерфейсного" бита был предназначен в шутку.

Кроме того, и я мог быть неправым здесь, я. Затем не метод Объекта, согласно Вашему определению типа, это был бы метод Интерфейса!

Переопределите свою функцию

  TSomeObject = class(TObject)
  public
        procedure Move(Const AMoveIntf: ISomeInterface);
  end;

  Procedure TSomeObject.Move(Const AMoveIntf : ISomeInterface);
  Begin
       ....;
       AMoveIntf.Next;
  end;

  O.Move(I);

Надеюсь, это поможет.

1
ответ дан 3 December 2019 в 07:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: