Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics Deriving

Tags:

c#

oop

I have situation like following:

public interface I {}
public class D1 : I {}
public class D2 : I {}

public class A
{
    public List<D1> Collection {get;set;}
    //Other Members
}
public class B
{
    public List<D2> Collection {get;set;}
    //Other Members
}

So, both A and B have List with elements derived from I.

How can I define base class for A and B?

P.S. I Tried to generalize base class:

class Base<T> where T : I
{
   List<T> Collection {get;set;}
}
A:Base<D1>{..}; B:Base<D2> {..}

But it gives me nothing (or I only think so) : I can't do so:

Base<I> b; b= new A(); b= new B();

because it is impossible to cast from List<I> to List<D1>

Thanks

like image 967
Ihar Krasnik Avatar asked Sep 13 '26 07:09

Ihar Krasnik


1 Answers

If you think about it, it does make sense.

Consider this:

Base<I> b = new B();
b.List.Add(new D1);

Theoretically, that would be valid code. Base<I>.List is a List<I>. D1 inherits from I. But we know that List is really List<D2> (as defined in B). Therefore our call to Add can't possibly work.

If you don't need to actually add items to the collection, you can switch some things around to make it work:

public interface IBase<out T> where T : I
{
    IEnumerable<T> Collection { get; }
}

public class A : IBase<D1>
{
    IEnumerable<D1> Collection { get; private set; }

    public A(IEnumerable<D1> list)
    {
        Collection = list;
    }
}

public class B : IBase<D2>
{
    IEnumerable<D2> Collection { get; private set; }

    public B(IEnumerable<D2> list)
    {
        Collection = list;
    }
}
like image 117
Justin Niessner Avatar answered Sep 14 '26 21:09

Justin Niessner