0

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);
    }
}
Kachou
  • 83
  • 1
  • 1
  • 10
  • You are looking for "C# variance for interfaces". Someone may find good duplicate or copy-paste existing answer. http://stackoverflow.com/questions/2033912/c-sharp-variance-problem-assigning-listderived-as-listbase should give good starting point to reach `public interface IRule ` as the change you are looking for. – Alexei Levenkov Jun 26 '15 at 21:20

1 Answers1

4

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>).

Jashaszun
  • 9,207
  • 3
  • 29
  • 57