Variance for interface tree structure

86 views Asked by At

I am struggling to cast in a tree hierarchy structure below is an example of the class hierarchy structure I would really appreciate if someone can point me in the right direction.

I am unable to cast

var myobj2 = (IR<JB>)JR;

Classes:

public class BASEA{ }
public class B: BASEA{ }
public class C: B{ }

public interface IR<T> { }

public abstract class JR<T> : IR<T> where T : B
{ public abstract void SetRule(); }


public class Action: JB<C>
{
    public override void SetRule()
    {
       //Logic
    }
}

public static class RuleLib 
{

    public static void ApplyTest<T>(T obj, IR<T> JB) where T:B
    {
        var myobj2 = (IR<JB>)JR; //=> does not cast!
    }
}
public class Test
{
    [Test]
    public void demo()
    {
        var obj = new B();
        var action = new Action();
        RuleLib.ApplyRule(obj,action);
    }
}
1

There are 1 answers

0
Jashaszun On BEST ANSWER

For this to work, your IRule interface needs to be covariant. The example given here shows the following covariance:

IEnumerable<Derived> d = new List<Derived>();
IEnumerable<Base> b = d;

This is basically exactly what you're doing. So in your code all you need to do is write

public interface IRule<out T> { ... }

instead of

public interface IRule<T> { ... }

This makes it so that you can cast from an IRule<U> to IRule<V> where U is a subclass of V (e.g. casting from IRule<ShiftAction> to IRule<Job>).