On Thu, 24 Mar 2005, ml wrote:
[Cut] > > > > > > procedure MyXYZPart.DoReport(aRep: IReportable); > > > begin > > > if (aRep <> nil) then begin > > > if (aRep is ILogged) then > > > (aRep as ILogged).Log(aRep.Report) > > > else > > > aRep.Report > > > end; > > > > I see what you want, but if you would do > > > > procedure MyXYZPart.DoReport(aRep: TInterfacedObject); > > > > begin > > if (aRep <> nil) and arep is IReportable then begin > > if (aRep is ILogged) then > > (aRep as ILogged).Log(aRep.Report) > > else > > aRep.Report > > end; > > > > you would have the same effect ? > > > > Yeah, exactly like this. And now the bug of this effect. With this you > get a whole bunch of calling procedures and functions and all are > accepting TInterfacedObject parameter. You don't know what actual > parameter is. With passing interfaces as parameters code is much > cleaner. And all functions are defined as restrictive what kind of > interface is accepted. OK, now I see where you're going. Your last sentence means: I want DoReport to accept only an 'IReportable' But at the same time, your code is checking that behind 'IReportable' there is also an 'ILogged'. I find this a bit contradictory; If you pass an TInterfacedObject, then you can check for as much classes or interfaces as you want. The code remains the same. But this is not a principal question. More important is: what happens if IReportable is an interface obtained from Windows ? How can you tell whether an interface comes from a Pascal class, or was obtained from a Windows OLE or ActiveX server ? There may not be a a real class behind IReportable. You can construct IReportable interfaces on the fly. (OpenOffice does it, and I think some SOAP implementations as well) > > Necessarily, there is always SOME instance implementing any interface... > > > > > > > > Meaning, that if I derived some class as (and call DoReport with it as > > > parameter) > > > type > > > TSomeClass = interface(TInterfacedObject, IReportable, ILogged) > > > > > > this class will have to contain all the logging facility needed, and > > > that's conditioned with interfaces (otherwise it won't be compiled). > > > > > > TSomeClass2 = interface(TInterfacedObject, IReportable) > > > > > > this class will automatically skip logging, because logging interface is > > > not supported by class > > > > > > What is difference here? I could pass a simple interfaced object as > > > parameter and predict possibility of logging. If object or interface > > > support that option then all the facility needed is supported and > > > logging is done. > > > > > > This is how and why interfaces should be used, for predicting features. > > > And with interfaces as they are this is just impossible. > > > > But with a slight change in your code, I think it is, see above ? > > > > I see, and I named you reason why. Mostly readability of your code. > > > If I understand you correct, you want to query the instance 'behind' > > some interface to see if it inmplements another interface, without > > having to access the actual instance ? > > > > Yes. > > > This still does not explain why you would need to do > > > > AClassInstance := AnInterface; > > > > The only reason why, is mostly internal (where vmt problems were > discussed). If "is" and "as" would be solved as I suggested, this isn't > necessary anymore. Meaning I can test if original object (and not > interface) implements some other interface and then act as that > interface, then this is not necessary anymore. > > Having ability to do > > if (aRep is ILogged) then > (aRep as ILogged).Log(aRep.Report); > > would make clean code, where possible calling parameter is obvious > > Second reason why could be treated as internal too. > > For now you have to specify properties as > > type > IA = interface > function GetSome: integer; > procedure SetSome(aValue: integer); > property Some: integer read GetSome write SetSome; > end; > > this is needed because interface has no clue of original vmt. while > blind properties definition would be > > type > IA = interface > property Some: integer read object write object; > end; > > and the implementation of property is left to class, not conditioned > with function and procedure I think the properties are needed, to remain compatible with COM interfaces, which only have methods, I think CORBA has this restriction too; They don't have 'properties'. After all the discussion, I see 2 real improvements: - To be able to use 'Is' operator on interfaces. (so without the need for 'Supports') - Use 'as' on interfaces. (But this should be possible as in Delphi) As for querying the class behind the interface: first you need to answer the windows problem. Michael. _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal