title: Delphi: How to implement QueryInterface of IUnknown?
body: <p>In Delphi, <code>IUnknown</code> is declared as:</p>
  
  <pre><code>function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
  </code></pre>
  
  <p><strong>Note:</strong> The output parameter is untyped</p>
  
  <p>In my <code>TInterfacedObject</code> descendant i need to handle <code>QueryInterface</code>, so i can return an object that supports the requested interface:</p>
  
  <pre><code>function TFoo.QueryInterface(const IID: TGUID; out Obj): HResult;
  begin
     if IsEqualGUID(IID, IFooBar) then
     begin
        Obj := (TFooBar.Create(Self) as IFooBar);
        Result := S_OK;
     end
     else
        Result := inherited QueryInterface(IID, {out}Obj);
  end;
  </code></pre>
  
  <p>The problem comes on the line:</p>
  
  <pre><code>Obj := (TFooBar.Create(Self) as IFooBar);
  </code></pre>
  
  <p>Delphi complains: </p>
  
  <blockquote>
    <p>Operator not applicable to this operand type</p>
  </blockquote>
  
  <p>Obviously i don't know how or what to assign to an <strong>untyped</strong> <code>out</code> parameter. i can randomly try things, in hopes that the compiler will stop complaining:</p>
  
  <pre><code>Obj := TFooBar.Create(Self);
  
  Obj := Pointer(TFooBar.Create(Self));
  
  Obj := Pointer(TFooBar.Create(Self) as IFooBar);
  </code></pre>
  
  <p>Ignoring all the code i've written (if required): how do i implement <code>QueryInterface</code> in an object descendant from <code>TInterfacedObject</code>?</p>
  
  <hr>
  
  <p>The real problem i've been trying to solve can be boiled down to i want to:</p>
  
  <blockquote>
    <p>i want to override methods in an interface</p>
  </blockquote>
  
  <p>In the same way:</p>
  
  <pre><code>TList = class(TObject)
  ...
     function GetItem(Index: Integer): Pointer; 
     procedure SetItem(Index: Integer; Value: Pointer);
     property Items[Index: Integer]: Pointer read GetItem write SetItem;
  end;
  </code></pre>
  
  <p>can be overridden in a descendant class:</p>
  
  <pre><code>TStudentList = class(TList)
  ...
     function GetItem(Index: Integer): TStudent; 
     procedure SetItem(Index: Integer; Value: TStudent);
     property Items[Index: Integer]: TStudent read GetItem write SetItem;
  end;
  </code></pre>
  
  <p>i want to so the same with interfaces:</p>
  
  <pre><code>IFoo = interface(IUnknown)
  ...
     function GetItem(Index: Variant): Variant; 
     procedure SetItem(Index: Variant; Value: Variant);
     property Items[Index: Variant]: Variant read GetItem write SetItem;
  end;
  
  IFooGuidString = interface(IFoo)
  ...
     function GetItem(Index: TGUID): string ; 
     procedure SetItem(Index: TGUID; Value: string );
     property Items[Index: TGUID]: string read GetItem write SetItem;
  end;
  </code></pre>
  
  <p>Problem is that how i have to begin loading up my implementing object with:</p>
  
  <pre><code>TFoo = class(TInterfacedObject, IFoo, IFooGuidString)
  public
     function IFoo.GetItem = FooGetItem;
     procedure IFoo.SetItem = FooSetItem;
     function FooGetItem(Index: Variant): Variant; 
     procedure FooSetItem(Index: Variant; Value: Variant);
  
     function IFooGuidString.GetItem = FooGuidStringGetItem;
     procedure IFooGuidString.SetItem = FooGuidStringSetItem;
     function FooGuidStringGetItem(Index: TGUID): string ; 
     procedure FooGuidStringSetItem(Index: TGUID; Value: string );
  end;
  </code></pre>
  
  <p>And there isn't just the two methods in <code>IFoo</code>, there's 6. And then if i want to add another supported interface:</p>
  
  <pre><code>IFooInt64String = interface(IFoo)
  ...
     function GetItem(Index: Int64): string ; 
     procedure SetItem(Index: Int64; Value: string );
     property Items[Index: Int64]: string read GetItem write SetItem;
  end;
  
  
  TFoo = class(TInterfacedObject, IFoo, IFooGuidString)
  public
     function IFoo.GetItem = FooGetItem;
     procedure IFoo.SetItem = FooSetItem;
     function FooGetItem(Index: Variant): Variant; 
     procedure FooSetItem(Index: Variant; Value: Variant);
  
     function IFooGuidString.GetItem = FooGuidStringGetItem;
     procedure IFooGuidString.SetItem = FooGuidStringSetItem;
     function FooGuidStringGetItem(Index: TGUID): string ; 
     procedure FooGuidStringSetItem(Index: TGUID; Value: string );
  
     function IFooInt64String.GetItem = FooInt64StringGetItem;
     procedure IFooInt64String.SetItem = FooInt64StringSetItem;
     function FooInt64StringGetItem(Index: Int64): string ; 
     procedure FooInt64StringSetItem(Index: Int64; Value: string );
  end;
  </code></pre>
  
  <p>And things get really unwieldy very fast.</p>