开发者

Delphi IS operator - Operator not applicable to this operand type

I guess this should be an easy one cause I must be doing something wrong.

this is my code, I'm trying to do a Strategy pattern in 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.FCounte开发者_开发问答r := 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.

And the if FStrategy is TStrategy1 then is giving me: Operator not applicable to this operand type. What am I doing wrong here cause this should work as I understand from a lot of Delphi language references?


You have omitted the GUID from your interface. is can't work without it.

Edit: On second glance, it still won't work. You can't use is to test an interface reference for its implementing object typein Delphi (well, not directly, anyway). You should change your design. For example, you could either alter the interface or add another interface to return a description of the implementation.


You could make this work by adding the IID/GUID as Craig states, and then changing SwitchStrategy to:

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

This only works with more modern versions of Delphi. I think Delphi 2010 was where the ability to cast an interface to its implementing object was added.


However, I'd be inclined to avoid this solution and go for something like this:

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;

When you find yourself asking an object what type it is, that's usually indicative of a design weakness.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜