tags:

views:

374

answers:

3

I have a base class that inherits List<> which has multiple classes derived from it.

I want to create a method that can add items to any class that has inherited from this base class, is this possible ?

pseudo code:

public class BaseList<T> : List<T> where T: baseItem
{
}

public BaseList<T> AddItems<T>(int someArg) where T: new(), baseItem
{

BaseList<T> temp = new BaseList<T>();
temp.add(new T());
temp.add(new T());
return temp;
} 

public class MyDerived: BaseList<SomeClass>
{
}

Then to call this code:

MyDerived temp = (MyDerived)AddItems();

is something like this possible ? I can't figure out the correct syntax

+4  A: 

Do you really need to derive from List<T> instead of using composition?

It sounds like you want a static method in a non-generic type:

public static TList CreateList<TList,TItem>(int someArg)
    where TList : BaseList<TItem>, new()
    where TItem : baseItem, new()
{
    TList temp = new TList();
    temp.Add(new TItem());
    temp.Add(new TItem());
    return temp;
}

It doesn't seem particularly nice though... perhaps if you explained the purpose of this, we could come up with a better idea.

Jon Skeet
There's an error in your code; fix it to TList temp = new TList();
configurator
A: 

You could also use

public static void AddItems<T>(List<T> list, int someArg) where T: new() {
    list.Add(new T());
    list.Add(new T());
}

And call it like so:

List list = new List<SomeClass>();
AddItems(list, someArg);
configurator
+2  A: 

I can't really understand your question but I have run into this problem before. If you ran into the same problem as me: you don't know the <T> parameter at compile time. Fortunately, this is a cynch to solve using interfaces - you can create a stronger type binding by using a non-generic interface.

class Program
{
    static void Main(string[] args)
    {
        IAddBaseItem addItem = new DerivedList();
        BaseItem item = new DerivedItem();
        IgnorantMethod(addItem, item);
    }

    static void IgnorantMethod(IAddBaseItem list, BaseItem item)
    {
        list.Add(item);
    }
}

class BaseItem
{
}

class BaseList<T> : List<T>, IAddBaseItem
{
    #region IAddBaseItem Members

    void IAddBaseItem.Add(BaseItem item)
    {
        if (item == null)
            Add(item);
        else
        {
            T typedItem = item as T;
            // If the 'as' operation fails the item isn't
            // of type T.
            if (typedItem == null)
                throw new ArgumentOutOfRangeException("T", "Wrong type");
            Add(typedItem);
        }
    }

    #endregion
}

class DerivedList : BaseList<DerivedItem>
{
}

class DerivedItem : BaseItem
{
}

interface IAddBaseItem
{
    void Add(BaseItem item);
}

As I said, this is my best guess as to what you are asking.

Jonathan C Dickinson