<p>Am 12.11.2016 04:46 schrieb "Ryan Joseph" <<a href="mailto:ryan@thealchemistguild.com">ryan@thealchemistguild.com</a>>:<br>
><br>
><br>
> > On Nov 12, 2016, at 3:22 AM, Jonas Maebe <<a href="mailto:jonas.maebe@elis.ugent.be">jonas.maebe@elis.ugent.be</a>> wrote:<br>
> ><br>
> > You're passing a class, not an object. Passing a class that implements an interface to a method that expects that interface should work fine. Converting a class instance to an interface that it implements is trivial and always works, it's doing the opposite that is hard and that requires specific support in the interface.<br>
><br>
> Here’s a better example of where this breaks. Yes casting does work to an extent but breaks eventually down the chain when I lose the reference. Is there anyway to get around this? Maybe I could store the reference from Supports inside TMyObjectClass so I don’t need to call Supports again?<br>
><br>
> type<br>
>         IMyInterface = interface<br>
>           procedure DoSomething;<br>
>                 function GetObject: TObject;<br>
>          end;<br>
><br>
> type<br>
>         TMyObjectClass = class(IMyInterface)<br>
>                 procedure DoSomething;<br>
>                         function GetObject: TObject;<br>
>         end;<br>
><br>
> var Obj: TMyObjectClass<br>
> ObjInt: IMyInterface;<br>
><br>
> Obj := TMyObject.Create;<br>
> ObjInt := Obj; // this works fine, casting to an interface<br>
><br>
> // Unit A only knows about IMyInterface so we pass<br>
> // the class cast as an interface (not sure what to call this)<br>
> DomeSomethingInUnitA(ObjInt);<br>
><br>
> // Unit A<br>
> var Obj: TObject;<br>
> Arr: TArray; // collection class the stores TObject<br>
><br>
> Arr := TArray.Create;<br>
> Obj := ObjInt.GetObject;<br>
> Arr.AddObject(Obj);</p>
<p>*Here* is your problem. You should use a container class that handles your interface type to store your interface reference. Especially generics come to mind here (e.g. fgl's TFPGList<> or Generics.Containers' TList<>).<br>
Also it's a bad design that you work with an interface and then assume that it's baked by a TObject instance. E.g. with a COM interface it might come from some C++ code. Then what?</p>
<p>> [do some stuff]<br>
><br>
> // here the problems start because TArray always returns TObject<br>
> // and I can’t cast TObject to IMyInterface even though the object<br>
> // stored in the array does in fact implement IMyInterface<br>
><br>
> ObjInt := IMyInterface(Arr.GetObject(0)); // error! but I need to get a reference to IMyInterface from the array<br>
><br>
> // I have to use “as” or Supports here and it defeats the purpose<br>
> ObjInt := Arr.GetObject(0) as IMyInterface;</p>
<p>Avoid this casting by storing the interface reference. Will make your life much easier and your code more maintainable.</p>
<p>Regards,<br>
Sven<br>
</p>