locked
How to define a generic collection of generic classes? RRS feed

  • Question

  • I've run into a bit of an interesting puzzle and I would love to see what some other developers thought about how to solve this. Here is my situation:

    I have an abstract generic class RecordHandler:

    public abstract class AbstractRecordHandler<T> where T:AbstractRecord{...}

    I have a few concrete implementations that inherit from AbstractRecordHandler.

    I want to declare a collection of AbstractRecordHandlers, but I dont know the syntax.

    This:
    List<AbstractRecordHandler<T>> recordHandlers = new List<AbstractRecordHandlers<T>>();

    does not compile, because "T" is undefined.

    has anyone else run in to this situation?
    Thursday, January 10, 2008 1:21 AM

Answers

  • I think, you should use a concrete type in order to declare a generic variable

    List<AbstractRecordHandler<String>> recordHandlers = new List<AbstractRecordHandlers<String>>();


    Code Block

        public abstract class ClassAb <T>

        {

        }

     

        public class ClassImp1<T> : ClassAb<T>

        {

        }

     

        public class TestClass

        {

            public TestClass()

            {

                //Error: The type or namespace name 'T' could not be found

                ClassImp1<T> mybadClass = new ClassImp1<T>();

     

                // only concrete declaration will be compiled

                List<ClassImp1<String>> myList = new List<ClassImp1<string>>();

            }

        }


    Generic classes that inherit from open constructed types must supply type arguments for any base class type parameters that are not shared by the inheriting class, as demonstrated in the following code:

    C#

    class BaseNodeMultiple<T, U> { }

     

    //No error

    class Node4<T> : BaseNodeMultiple<T, int> { }

     

    //No error

    class Node5<T, U> : BaseNodeMultiple<T, U> { }

     

    //Generates an error

    //class Node6<T> : BaseNodeMultiple<T, U> {}

    __________

    Nota bene also, that open constructed and closed constructed types can be used as method parameters:
    void Swap<T>(List<T> list1, List<T> list2)
    {
    //code to swap items
    }

    void Swap(List<int> list1, List<int> list2)
    {
    //code to swap items
    }

    Generic classes are invariant. In other words, if an input parameter specifies a List<BaseClass>, you will get a compile-time error if you attempt to provide a List<DerivedClass>.


    see more...
    Thursday, January 10, 2008 6:33 AM