0

これが私のタイプです...

unit unitTestInterfaces;

interface
type
  IFoo = interface
    ['{169AF568-4568-429A-A8F6-C69F4BBCC6F0}']
    function TestFoo1:string;
    function TestFoo:string;
  end;

  IBah = interface
    ['{C03E4E20-2D13-45E5-BBC6-9FDE12116F95}']
    function TestBah:string;
    function TestBah1:string;
  end;

  TFooBah = class(TInterfacedObject, IFoo, IBah)
    //IFoo
    function TestFoo1:string;
    function TestFoo:string;

    //IBah
    function TestBah1:string;
    function TestBah:string;
  end;

implementation

{ TFooBah }

function TFooBah.TestBah: string;
begin
  Result := 'TestBah';
end;

function TFooBah.TestBah1: string;
begin
  Result := 'TestBah1';
end;

function TFooBah.TestFoo: string;
begin
  Result := 'TestFoo';
end;

function TFooBah.TestFoo1: string;
begin
  Result := 'TestFoo1';
end;

end.

そして、これが例を実行するための私のコードです...

var
  fb:TFooBah;
  f:IFoo;
  b:IBah;
begin
  try
    fb := TFooBah.Create;

    /// Notice we've used IBah here instead of IFoo, our writeln() still outputs the
    /// result from the TestBah() function, presumably because it's the "first" method
    /// in the IBah interface, just as TestFoo1() is the "first" method in the IFoo
    /// interface.
    (fb as IUnknown).QueryInterface(IBah,f); //So why bother with this way at all??
    //f := fb as IBah; //causes compile error
    //f := fb; //works as expected
    if Assigned(f)then
    begin
      writeln(f.TestFoo1); //wouldn't expect this to work since "f" holds reference to IBah, which doesn't have TestFoo1()
    end;

    (fb as IUnknown).QueryInterface(IBah,b);
    if Assigned(f) then
    begin
      writeln(b.TestBah1);
    end;

  except on E:Exception do
    writeln(E.Message);
  end;
end.

QueryInterfaceの最初の呼び出しでは、「f」変数に間違ったタイプのインターフェイスを割り当てていても、それが指すメソッドとは対照的に、それが指しているものの「最初の」メソッドを実行しようとするようです。名前は「TestFoo1」です。f:= fbを使用すると期待どおりに機能するので、構文f:= fbの代わりにQueryInterfaceを使用する理由はありますか?

4

3 に答える 3

7

ここでルールを破っていると思います:

QueryInterface は、要求したインターフェースを f に入れます。f が適切な型であることは、ユーザーの責任です。2 番目のパラメーターは型指定されていないため、コンパイラーはエラーについて警告することができません。

于 2010-08-11T12:53:03.383 に答える
3

QueryInterfaceより良い構文は、 1つでも1つでもないと私は主張しますf := fb。それはあなたがコメントアウトしたものです:

f := fb as IBah; //causes compile error

それはまさにQueryInterface、引数をチェックしないという問題をカバーする型チェックがあるからです。

于 2010-08-11T13:09:34.013 に答える
2

f := Fb as IFoo、呼び出し Supports( Fb, IFoo ) などはすべてバックグラウンドで QueryInterface を呼び出すことに注意してください。そのため、QueryInterface メソッドが使用されますが、自動キャスト、is、as、およびサポートのようなメソッドで優れた構文が得られます。

于 2010-08-11T13:07:51.727 に答える