9

参照カウントのないインターフェイスを実装するクラスが必要です。私は次のことをしました:

  IMyInterface = interface(IInterface)
      ['{B84904DF-9E8A-46E0-98E4-498BF03C2819}'] 
      procedure InterfaceMethod;
  end;

  TMyClass = class(TObject, IMyInterface)
  protected
      function _AddRef: Integer;stdcall;
      function _Release: Integer;stdcall;
      function QueryInterface(const IID: TGUID; out Obj): HResult;stdcall;
  public
      procedure InterfaceMethod;
  end;

  procedure TMyClass.InterfaceMethod;
  begin
      ShowMessage('The Method');
  end;

  function TMyClass.QueryInterface(const IID: TGUID; out Obj): HResult;
  begin
      if GetInterface(IID, Obj) then
          Result := 0
      else
          Result := E_NOINTERFACE;
  end;

  function TMyClass._AddRef: Integer;
  begin
      Result := -1;
  end;

  function TMyClass._Release: Integer;
  begin
      Result := -1;
  end;

参照カウントの欠如は正常に機能します。しかし、私の懸念は、演算子TMyClassIMyInterface使用してキャストできないことです。as

var
  MyI: IMyInterface; 
begin
  MyI := TMyClass.Create as IMyInterface;

私は与えられています

[DCC エラー] E2015 このオペランド型には適用できない演算子

TMyClassから派生すると問題はなくなりますTInterfacedObject-つまり、コンパイラエラーなしでそのようなキャストを行うことができます。明らかに、TInterfacedObject を基底クラスとして使用したくありません。クラス参照がカウントされるからです。そのようなキャストが許可されないのはなぜですか? また、それを回避するにはどうすればよいですか?

4

1 に答える 1

15

コードで使用できない理由は、クラスがサポートされているインターフェイスのリストにas明示的にリストされていないためです。IInterfaceインターフェイスはから派生していますがIInterface、実際にそのインターフェイスをリストしない限り、クラスはそれをサポートしていません。

したがって、簡単な修正は、クラスを次のように宣言することです。

TMyClass = class(TObject, IInterface, IMyInterface)

クラスを実装する必要がある理由は、キャストIInterfaceを実装するためにコンパイラが依存していることです。as

私が言いたいもう1つのポイントは、一般に、インターフェイスの継承の使用は避けるべきであるということです。概して、それはほとんど目的を果たしません。インターフェイスを使用する利点の1つは、実装の継承に伴う単一の継承の制約から解放されることです。

ただし、いずれの場合も、すべてのDelphiインターフェイスは自動的に継承するIInterfaceため、この場合、それを指定する意味はありません。私はあなたのインターフェースを次のように宣言します:

IMyInterface = interface
  ['{B84904DF-9E8A-46E0-98E4-498BF03C2819}'] 
  procedure InterfaceMethod;
end;

より広義には、インターフェースで継承を使用しないように努める必要があります。このアプローチを採用することで、結合度が低くなり、柔軟性が向上します。

于 2013-02-18T08:32:30.310 に答える