title: DELPHI: Generics and polymorphism
body: <p>This has been asked several different ways already - but I haven't found my answer yet.</p>
  
  <p>Can someone clarify a few things for me please.
  Using : Delphi XE2</p>
  
  <p>I have quite a big BaseObject that I use for almost everything.
  Along with it I have a Generic list - BaseList.</p>
  
  <p>Delarations go like this :</p>
  
  <pre><code>TBaseObject = class
  ... a lot of properties and methods ...
  end;
  
  TBaseList&lt;T: TBaseObject&gt; = class(TObjectList&lt;T&gt;)
  ... some properties and methods ... 
  end;
  </code></pre>
  
  <p>I have recently tried to change the TBaseList declaration from a very old TStringList using Objects[] property... to this never more versatile Generics list TObjectList.</p>
  
  <p>But I run into some problems.
  The BaseUnit is one file ... and every time I descend my BaseObject I also make a specialized list to follow it.</p>
  
  <p>So I would go and do something like :</p>
  
  <pre><code>TCustomer = class(TBaseObject)
  ... customer related stuff ...
  end;
  
  TCustomerList&lt;T: TCustomer&gt; = class(TBaseList&lt;T&gt;)
  ... customer list specific stuff ...
  end;
  </code></pre>
  
  <p>But now I would like an object to contain a list - that can hold any object.
  And I thought I could do it like this</p>
  
  <pre><code>TControlObject = class(TBaseobject)
    FGenList: TBaseList&lt;TBaseObject&gt;; 
  end;
  </code></pre>
  
  <p>Since BaseList and BaseObject is top of my hierarchy I assumed that such a List would be able to hold any list I could think of.</p>
  
  <p>But I have a feeling that it is here I fail ...
  a <code>TBaseList&lt;TBaseobject&gt;</code> is somehow not comparable to <code>TCustomerList&lt;TCustomer&gt;</code> ...
  Even if <code>TCustomerList</code> and <code>TCustomer</code> is descended from my base.</p>
  
  <p>I was hoping to be able to use generics in the baselist for instaciating new objects.
  ie. using <code>T.Create</code> in a populate method. </p>
  
  <p>Here is example of complete hierarchy:</p>
  
  <pre><code>Base Unit;
  TBaseObject = class
  end;
  TBaseList&lt;T:TBaseObject&gt; = class(TObjectList&lt;T&gt;)
  end;
  
  CustomCustomer Unit;
  TCustomCustomer = class(TBaseObject) 
  end;
  TCustomCustomerList&lt;T:TCustomCustomer&gt; = class(TBaseList&lt;T&gt;)
  end;
  
  Customer Unit;
  TCustomer = class(TCustomCustomer)
  end;
  TCustomerList&lt;T:TCustomer&gt; = class(TCustomCustomerList&lt;T&gt;)
  end;
  
  CustomPerson Unit;
  TCustomPerson = class(TBaseObject) 
  end;
  TCustomPersonList&lt;T:TCustomPerson&gt; = class(TBaseList&lt;T&gt;)
  end;
  
  Person Unit;
  TPerson = class(TCustomPerson)
  end;
  TPersonList&lt;T:TPerson&gt; = class(TCustomPersonList&lt;T&gt;)
  end;
  </code></pre>
  
  <p>Given the above hierarchy - why can't I :</p>
  
  <pre><code>var    
    aList : TBaseList&lt;TBaseObject&gt;;  // used as a list parameter for methods
    aPersonList : TPersonList&lt;TPerson&gt;;
    aCustomerList : TCustomerList&lt;TCustomer&gt;;
  begin
    aPersonList := TPersonList&lt;TPerson&gt;.Create;
    aCustomerList := TCustomerList&lt;TCustomer&gt;.Create;
  
    aList := aCustomerList;  &lt;-- this FAILS !!  types not equal ..
  
  end;
  </code></pre>
  
  <p>Calling a procedure that handles the base class for all lists fails the same way ...</p>
  
  <pre><code>Procedure LogStuff(SomeList : TBaseList&lt;TBaseObject&gt;)
  begin
    writeln(Format( 'No. Elements in list : %d',[SomeList.Count]));
  end;
  </code></pre>
  
  <p>Can someone punch me and tell me what I'm doing wrong here?</p>