Reputation: 6434
I am trying to get to grips with more complicated inheritance structures and generics and I am trying to create some architecture for a current project which is following this suit. My problem currently is I am getting this error:
Type argument 'Foo' does not inherit from or implement the constraint type 'ListBase'
public class ItemBase {}
public class ListBase<T> where T : ItemBase
{
public virtual List<T> ListExample {get; set; }
}
These are my base classes, although they probably aren't named appropriately I have just tried to show a simple example of what I am trying to achieve.
public class FooItem : ItemBase { }
public class Foo : ListBase<FooItem>
{
public override List<FooItem> ListExample { get; set;}
}
So I can then extend the initial base class for the lists and do more with it, but I want a generic way of handling all of these classes.
public class ListHandler<T> where T : ListBase<ItemBase> { }
When I try to pass Foo
as T
to the ListHandler
I get the error mentioned, I thought that inevitably because Foo
is a List<ItemBase>
and FooItem
is of type ItemBase
I would be able to do this var handler = new ListHandler<Foo>();
.
Could anybody explain why I can't do this or what I am doing wrong?
Upvotes: 1
Views: 89
Reputation: 13215
You need to supply the type parameter of the item type, not the list type. To clarify this, try expanding the ListHandler
class to include an AddItem
method which adds a ItemBase
item to a ListBase
instance:
// As is: Won't work, because there is no way to refer to the constructed
// specific type of ItemBase:
public class ListHandler<TList> where TList: ListBase {
public TList List { get; private set; }
public ListHandler(TList List) { this.List = List; }
public void AddItem(T???? item) { List.ListExample.Add(item); }
}
// Corrected: this will work because TItem can be used to constrain
// the constructed ListBase type as well:
public class ListHandler<TItem> where TItem : ItemBase {
public ListBase<TItem> List { get; private set; }
public ListHandler(ListBase<TItem> List) { this.List = List; }
public void AddItem(TItem item) { List.ListExample.Add(item); }
}
// And this will work just fine:
var handler = new ListHandler<FooItem>(new FooList());
Upvotes: 0
Reputation: 887215
A ListBase<ItemBase>
is not the same as a ListBase<FooItem>
.
In particular, you can add any kind of ItemBase
to a ListBase<ItemBase>
.
You need to accept two generic parameters:
public class ListHandler<TList, TItem> where T : ListBase<TItem> where TItem : ItemBase { }
Upvotes: 4