Delphi IS运算符 - 运算符不适用于此操作数类型

时间:2011-03-24 16:07:45

标签: delphi

我想这应该是一件容易的事,因为我必须做错事。

这是我的代码,我正在尝试在Delphi中执行策略模式:

unit Pattern;

interface

type

  TContext = class;

  IStrategy = interface
    function Move(c: TContext): integer;
  end;

  TStrategy1 = class(TInterfacedObject, IStrategy)
  public
    function Move(c: TContext): integer;
  end;

  TStrategy2 = class(TInterfacedObject, IStrategy)
  public
    function Move(c: TContext): integer;
  end;

  TContext = class
  const
    START = 5;
  private
    FStrategy: IStrategy;
  public
    FCounter: integer;
    constructor Create;
    function Algorithm(): integer;
    procedure SwitchStrategy();
  end;

implementation

{ TStrategy1 }

function TStrategy1.Move(c: TContext): integer;
begin
  c.FCounter := c.FCounter + 1;
  Result := c.FCounter;
end;

{ TStrategy2 }

function TStrategy2.Move(c: TContext): integer;
begin
  c.FCounter := c.FCounter - 1;
  Result := c.FCounter;
end;

{ TContext }

function TContext.Algorithm: integer;
begin
  Result := FStrategy.Move(Self)
end;

constructor TContext.Create;
begin
  FCounter := 5;
  FStrategy := TStrategy1.Create();
end;

procedure TContext.SwitchStrategy;
begin
  if FStrategy is TStrategy1 then
    FStrategy := TStrategy2.Create()
  else
    FStrategy := TStrategy1.Create();
end;

end.

如果FStrategy是TStrategy1然后给我:操作符不适用于此操作数类型。 我在这里做错了什么因为我应该从大量的Delphi语言参考中理解这一点?

2 个答案:

答案 0 :(得分:11)

您已从界面中省略了GUID。如果没有它,is就无法运作。

编辑:乍一看,它仍然无效。您无法使用is在Delphi中测试其实现对象类型的接口引用(不管怎么说,不是直接)。你应该改变你的设计。例如,您可以更改接口或添加另一个接口以返回实现的描述。

答案 1 :(得分:6)

您可以通过将IID / GUID添加为Craig状态,然后将SwitchStrategy更改为:

来完成此工作
procedure TContext.SwitchStrategy;
begin
  if (FStrategy as TObject) is TStrategy1 then
    FStrategy := TStrategy2.Create()
  else
    FStrategy := TStrategy1.Create();
end;

这仅适用于更现代版本的Delphi。我认为Delphi 2010是添加界面到其实现对象的能力的地方。


但是,我倾向于避免这种解决方案,并采取类似的措施:

type
  IStrategy = interface
    function Move(c: TContext): integer;
    function Switch: IStrategy;
  end;

  TStrategy1 = class(TInterfacedObject, IStrategy)
  public
    function Move(c: TContext): integer;
    function Switch: IStrategy;
  end;

  TStrategy2 = class(TInterfacedObject, IStrategy)
  public
    function Move(c: TContext): integer;
    function Switch: IStrategy;
  end;

function TStrategy1.Switch: IStrategy;
begin
  Result := TStrategy2.Create;
end;

function TStrategy2.Switch: IStrategy;
begin
  Result := TStrategy1.Create;
end;

procedure TContext.SwitchStrategy;
begin
  FStrategy := FStrategy.Switch;
end;

当你发现自己问对象是什么类型时,这通常表明设计存在缺陷。