Thanks for your explanations, Rob, 

OK, also for the records of this e-list: 

   list:=TObjectList.create;
   list.add(TSubObject.create);
   boolVar:=supports(list[0],IBlah,IBlahRef);
   if bool
      then IBlahRef.hello;

So the sollution is: 

* use a TObjectList or a TInterfaceList to make the elements of the list 
assignable to 
Interface variables. Both seem to work. 
* For the actual assignment, the supports function is used. 


Rinke

(by the way: testRef3 in my original post should of course be subObjRef)




On 16 Feb 2006 at 22:02, Rob Kennedy wrote:

> rinke hoekstra wrote:
> > I cannot assign elements from a list to an interface type reference. 
> 
> You might benefit from reading this article:
> 
> http://www.cs.wisc.edu/~rkennedy/interface-object
> 
> > Given the following (simplified) class and interface definitions: 
> > 
> >   IBlah = Interface
> >      procedure hello;
> >   end;
> > 
> >   TTestObject = class(TInterfacedObject, IBlah)
> >      procedure hello;
> >   end;
> > 
> >   TSubObject = class(TTestObject)
> >      procedure boeh;
> >   end;
> > 
> > 
> > Assigning a variable of tyep TsubObject to an IBlah reference type works 
> > perfectly: 
> > 
> > var 
> >     iBlahRef: IBlah;
> >     subObjRef: TSubObject;
> > 
> > begin
> >    subObjRef:=TSubObject.create;
> >    iBlahRef:=IBlah(testref3);               //works fine
> 
> Works fine? It doesn't even compile. What's testref3?
> 
> > When I first put the refs in a list, and then try to get them from the 
> > list, it does not work 
> > anymore: 
> > 
> > var 
> >     iBlahRef: IBlah;
> >     subObjRef: TSubObject;
> > 
> > begin
> >    l:=TList.create;
> >    l.add(TSubObject.create);
> >    iBlahRef:=IBlah(l[0]);           //does not work, null pointer exception
> 
> That's not a safe type cast. What you put into the list was a TSubObject 
> reference. That's what you get out, too, except that its type is reduced 
> to Pointer since that's what TList stores.
> 
> Once you get the Pointer back, you type-cast it to IBlah. But the 
> address you got doesn't represent an IBlah. It represents a TSubObject. 
> The compiler doesn't know that, though, so it simply treats the Pointer 
> as an IBlah when it does the assignment to iBlahRef.
> 
> When you type-cast an actual object reference to an interface type, the 
> compiler inserts extra code to fetch the object's interface reference. 
> It's not just a simple re-interpretation of the pointer value as a 
> different type. But type-casting a Pointer to an interface type *is* 
> just a re-interpretation.
> 
> > while, from the same list, this works: 
> >    testObjectRef:=TTestObject(l[0]);                //works fine
> > 
> > As both TTestObject variables and IBlah variables should be assignable to 
> > the elements 
> > of the list, both should work, isn't it?
> 
> Just because it's assignable *to* the list doesn't mean it's assignable 
> *from* the list.
> 
> > Then why can't I assign the elements from the list to an IBlah, where I can 
> > assign them 
> > to an TTestObject? Am I missing something, or is there some very silly 
> > error I am 
> > overlooking? 
> > 
> > Is there any way in which I can assign list elements to interface typed 
> > variables??
> 
> Well, you could start by using list classes that know something more 
> about the things they store. If you want to store objects, then use a 
> TObjectList. If you want to store interfaces, then use a TInterfaceList.
> 
> When you want to type-cast to an interface type, use the "as" keyword or 
> the Supports function, found in the SysUtils unit.
> 
> -- 
> Rob
> _______________________________________________
> Delphi mailing list -> [email protected]
> http://www.elists.org/mailman/listinfo/delphi


_______________________________________________
Delphi mailing list -> [email protected]
http://www.elists.org/mailman/listinfo/delphi

Reply via email to