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

ele*_*tor 3 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.
Run Code Online (Sandbox Code Playgroud)

如果FStrategy是TStrategy1然后给我:运算符不适用于此操作数类型.我在这里做错了什么导致这应该像我从许多Delphi语言参考中理解的那样工作?

Cra*_*ntz 11

您已从界面中省略了GUID.is没有它就无法工作.

编辑:乍一看,它仍然无法正常工作.你不能用它is来测试Delphi中实现对象类型的接口引用(好吧,不管怎么说).你应该改变你的设计.例如,您可以更改接口或添加另一个接口以返回实现的描述.

  • 详细说明,是QueryInterface的符号快捷方式,它请求由其IID标识的接口,Craig称之为GUID.通过将光标定位在`IStrategy = interface`下的空行并按CTRL + SHIFT + G来生成一个. (4认同)
  • @Craig从D2010开始,您可以从Delphi界面恢复实现对象. (2认同)

Dav*_*nan 6

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

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

这仅适用于更现代的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;
Run Code Online (Sandbox Code Playgroud)

当您发现对象是什么类型时,通常表明设计存在缺陷。

  • “当您发现对象是什么类型时,通常表明设计存在缺陷。” 生活的话。 (7认同)