Welcome to MSDN Blogs Sign in | Join | Help

Passing Generic List and inheritance ...

I came across this interesting scenario when I was looking into some issues. In a normal method you can pass the derived class instance when a base class instance is expected. In the example below passing dc1 to Method1 shows that you can indeed pass a derived class when a BaseClass was expected. But when you generate a generic List with a derived class and try passing it to function which was expecting a generic list with a base class it does not work. Strange, but I got the error mentioned below.

 

To work around it I made the list as a list of base class and limited to access of the derived class by checking on the type. It helps but is not as elegant as it should have been.

 

 

using System;

using System.Collections.Generic;

using System.Collections;

class BaseClass

{

    public int field1;

    public BaseClass()

    {

        field1 = 30;

    }

}

 

class DerivedClass : BaseClass

{

    int field2;

    DerivedClass()

    {

        field1 = 10;

        field2 = 20;

    }

    void Method1(BaseClass a)

    {

        Console.WriteLine("In method1 .." + field2);

    }

 

    void Method2(List<BaseClass> a)

    {

        for (int count = 0; count < a.Count; count++)

        {

            Console.WriteLine("In Method2 ... " + a[count].field1);

            // To be safe you check the type and so on ...

            //

            if (a[count].GetType() == typeof(DerivedClass))

            {

                Console.WriteLine("In method2 ... " + ((DerivedClass)a[count]).field2);

            }

        }

    }

 

    static void Main()

    {

        BaseClass bc1 = new BaseClass();

        DerivedClass dc1 = new DerivedClass();

        DerivedClass dc2 = new DerivedClass();

        dc2.Method1(dc1);

        // This will give you compilation error:

        //

        // List<DerivedClass> bcl = new List<DerivedClass>();

 

        // This will work

        //

        List<BaseClass> bcl = new List<BaseClass>();

        bcl.Add(dc1);

        bcl.Add(bc1);

        dc2.Method2(bcl);

    }

}

Published Tuesday, July 11, 2006 10:11 PM by thottams@microsoft.com

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Passing Generic List and inheritance ...

Hi Thottam,

I ran into the same situation when I used generics extensively for the first time. And I learned that this is expected behavior.
The reason is that Generics are invariant. An good explanation on that can be found at the generics faq at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/Fundamentals.asp
Cheers,
Dirk
Tuesday, July 11, 2006 7:07 PM by dirkpr

# re: Passing Generic List and inheritance ...

I did not know about this until I read the article you had mentioned. Thanks for the reference and the comments. I will try to write about that next time from what I understand!
Tuesday, July 11, 2006 7:27 PM by Thottam Sriram

# re: Passing Generic List and inheritance ...

.NET actually does support covariance, but C# doesn't expose it. It wouldn't work for List<T> anyway, since that accepts T in input argument positions - covariance can only work with output arguments. I discussed it on my own blog entry (linked).
Tuesday, July 11, 2006 7:45 PM by barrkel

# re: Passing Generic List and inheritance ...

Thanks Barrkel for the reference. It was an excellent read as well.
Thursday, July 13, 2006 5:08 PM by Thottam Sriram

# re: Passing Generic List and inheritance ...

You can get it to work if you make Method2 a generic method like this:

void Method2<T>(List<T> a) where T : BaseClass

{

...

}

This will work then:

List<DerivedClass> bc1 = new List<DerivedClass>;

dc2.Method2(bc1);

Thursday, August 23, 2007 9:34 AM by Nic Gorleer

# re: Passing Generic List and inheritance ...

Thanks Nic, just what I was looking for

Tuesday, July 07, 2009 5:26 AM by Kaarel

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker