Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having trouble with inherited classes, constructors with generics

I've got a semi-complex inheritance structure that I'm having difficulty with on overriding a constructor on a base class. The following code can show the error:

public abstract class MyBaseObject
{
    public MyBaseObject(MyBaseCollection<MyBaseObject> parent)
    {
        this.Parent = parent;
    }

    public MyBaseCollection<MyBaseObject> Parent { get; set; }
}

public abstract class MyBaseCollection<T>
    where T : MyBaseObject
{ }

public class MyRealObject : MyBaseObject
{
    public MyRealObject(MyRealCollection parent)
        : base(parent)
    { }

    public new MyRealCollection Parent { get { return (MyRealCollection)base.Parent; } }
}

public class MyRealCollection : MyBaseCollection<MyRealObject>
{ }

So, specifically, I can't override the constructor in the MyBaseObject class. Trying to pass in MyRealCollection in place of MyBaseCollection isn't acceptable. If I get rid of the generics arguments, it works; MyRealCollection is accepted in place of MyBaseCollection. But I really need the generics argument to make my collection classes work the way I need them to.

like image 511
Random Avatar asked Dec 13 '25 15:12

Random


1 Answers

I suggest you look into contravariance and covariance. Here might be a good start http://msdn.microsoft.com/en-us/library/dd799517.aspx

In short, the CLR can't assume what you want it to assume with respect to the type inheritance for some very well-defined reasons that are way above my pay grade.

However, you can do something like this if you play with the type hierarchy a little. I used IEnumerable to help.

public abstract class MyBaseObject
{
    public MyBaseObject(IEnumerable<MyBaseObject> parent)
    {
        this.Parent = parent;
    }

    public IEnumerable<MyBaseObject> Parent { get; set; }
}

public class MyRealObject : MyBaseObject
{ 
    public MyRealObject(MyRealCollection parent)
        : base(parent)
    { }

    public new MyRealCollection Parent { get { return (MyRealCollection)base.Parent; } }
}

public class MyRealCollection : IEnumerable<MyRealObject>
{ }
like image 59
Squirrelsama Avatar answered Dec 15 '25 11:12

Squirrelsama



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!