Re: [fpc-pascal] Interface performance

2016-11-12 Thread Sven Barth
Am 12.11.2016 04:46 schrieb "Ryan Joseph" :
>
>
> > On Nov 12, 2016, at 3:22 AM, Jonas Maebe 
wrote:
> >
> > 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.
>
> 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?
>
> type
> IMyInterface = interface
>   procedure DoSomething;
> function GetObject: TObject;
>  end;
>
> type
> TMyObjectClass = class(IMyInterface)
> procedure DoSomething;
> function GetObject: TObject;
> end;
>
> var Obj: TMyObjectClass
> ObjInt: IMyInterface;
>
> Obj := TMyObject.Create;
> ObjInt := Obj; // this works fine, casting to an interface
>
> // Unit A only knows about IMyInterface so we pass
> // the class cast as an interface (not sure what to call this)
> DomeSomethingInUnitA(ObjInt);
>
> // Unit A
> var Obj: TObject;
> Arr: TArray; // collection class the stores TObject
>
> Arr := TArray.Create;
> Obj := ObjInt.GetObject;
> Arr.AddObject(Obj);

*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<>).
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?

> [do some stuff]
>
> // here the problems start because TArray always returns TObject
> // and I can’t cast TObject to IMyInterface even though the object
> // stored in the array does in fact implement IMyInterface
>
> ObjInt := IMyInterface(Arr.GetObject(0)); // error! but I need to get a
reference to IMyInterface from the array
>
> // I have to use “as” or Supports here and it defeats the purpose
> ObjInt := Arr.GetObject(0) as IMyInterface;

Avoid this casting by storing the interface reference. Will make your life
much easier and your code more maintainable.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-12 Thread Andrew Haines

On 11/11/2016 10:14 PM, Ryan Joseph wrote:

Arr := TArray.Create;
Obj := ObjInt.GetObject;
Arr.AddObject(Obj);

[do some stuff]

// here the problems start because TArray always returns TObject
// and I can’t cast TObject to IMyInterface even though the object
// stored in the array does in fact implement IMyInterface

ObjInt := IMyInterface(Arr.GetObject(0)); // error! but I need to get a 
reference to IMyInterface from the array

// I have to use “as” or Supports here and it defeats the purpose
ObjInt := Arr.GetObject(0) as IMyInterface;


 You have two options if you have a list of TObject.

1.  (Arr.GetObject(n) as IMyInterface).DoSomething;

2.  TMyObjectClass(Arr.GetObject(n)).DoSomething;

2 is kind of pointless because the interface is not being used so why 
have it.


Probably it is better to keep a list of IMyInterface rather than TObject.


I made a small test and uploaded it to github if you want to check it 
out. It uses a list of IMyInterface.


https://github.com/andrewd207/interfacetest

Or as a zip:

https://github.com/andrewd207/interfacetest/archive/master.zip


Regards,

Andrew Haines
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Interface performance

2016-11-12 Thread Ryan Joseph

> On Nov 12, 2016, at 3:29 PM, Sven Barth  wrote:
> Avoid this casting by storing the interface reference. Will make your life 
> much easier and your code more maintainable.

Yes storing the interface works and seems to be the best solution for now. I 
did learn that generics could clean up the problem further but I need to adapt 
more code to make that work easily and removing the constant Support calls is 
good enough to put my mind at ease. :)

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal