2

Sorry for the bad title, but I didn't know how to entitle this in a good way.

Let the following interfaces :

interface IFoo
{
}

interface IBar
{
}

And the following classes :

class Base
{
}

class Derived1 : Base, IFoo, IBar
{
}

class Derived2 : Base, IFoo, IBar
{
}

I need to have a common type for Derived1 and Derived2 that has all the features of Base, IFoo and IBar. so that i can have instances of both Derived1 and Derived2 into the same collection and have access to the features of Base, IFoo and IBar without doing some reflexion black magic.

If Base was an interface, I would just have to create an interface requiring to implement Base, IFoo and IBar, but it's not the case.

I also do not want to have an intermediate inheritance between Derived1 / Derived2 and Base :

class Intermediate : Base, IFoo, IBar
{
}

class Derived1 : Intermediate
{
}

class Derived2 : Intermediate
{
}

Because I'm in the context of Unity and inheritance is to be avoided there more than anywhere.

Also I cannot modify Base.

I thought about having an IBase interface that requires all the features of Base and have an "intermediate" interface requiring to implement it too, i.e :

interface IIntermediate : IBase, IFoo, IBar
{
}

class Derived1 : Base, IIntermediate
{
}

class Derived2 : Base, IIntermediate
{
}

But I would have to copy all of the features of Base (and its parents) into IBase and IBase would also not be a Base. So that looks a bit dirty and might cause me problems I don't see yet.

I there a different way to acheive what I need to do other than the two possibilities mentionned above ? Thank you !

8
  • 2
    What exactly about Unity requires you to avoid inheritance? You're already inheriting from Base, it's unclear why an additional level of inheritance would be undesirable. Commented Oct 5, 2018 at 18:09
  • Could you please add the concrete types that you are actually wanting to derive from? What is Base? Commented Oct 5, 2018 at 18:11
  • Why can't you change Base? Commented Oct 5, 2018 at 18:13
  • Well Base is actually MonoBehaviour. I would like to avoid an extra level of inheritance, because when you declare a Unity "event" (such as Awake(), Update(), etc), you also have to manually call the parent one, if any. This is error prone and not nice to maintain. Commented Oct 5, 2018 at 18:15
  • 1
    So I see strong constraint for inheritance. If you want have an object that can refer to all derived class, make an interface that inherit all Interface except Base and use Tuple with the type parameter of Base and your new Interface, but both indicate to same object. It's just a relief not a strong solution. Commented Oct 5, 2018 at 18:25

1 Answer 1

1

How about a class with implicit operators to be able to get constructed and return all the desired types.

class MyBase : IFoo, IBar
{
    Base innerValue;
    public static implicit operator Base(MyBase value)
    {
        return value.innerValue;
    }

    public static implicit operator MyBase(Derived1 value)
    {
        return new MyBase(value);
    }

    public static implicit operator MyBase(Derived2 value)
    {
        return new MyBase(value);
    }

    public MyBase(Derived1 value)
    {
        innerValue = value;
    }
    public MyBase(Derived2 value)
    {
        innerValue = value;
    }
    // Implement IFoo and IBar based on innerValue calls
}

This would allow you to create an array like this:

MyBase[] myArray = new MyBase[] {new Derived1(), new Derived2()};

And you could still treat each instance as a Base:

Base B1 = myArray[0];
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your answer. Unfortunately I won't be able to do that because I must make my derived classes inherit from the base one, directly or indirectly. Sorry for not mentionning it. And also that base class wrapper would have to know about its subclasses and be modified anytime I create a new derived classes. Thanks for taking the time to help anyway. :)
@Virus721 Your Derived1 and Derived2 classes would still be inheriting from Base just as you had coded. That's what allows MyBase's operators to automaticaly convert from Derived1 to Base in the MyBase constructors.
Mmmhh true, I didn't understand properly. So I just make my derived classes inherit from the base one. The only difference is that the reference gets wrapped into this class so that they can be aded to the same collection ? I will try. I'll accept your answer cause it seems to answer the question, regardless of how it works for my real case. Thx
Seems to work nicely in my case ! I can probably improve maintainability using some generics.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.