接口树结构的差异

Variance for interface tree structure

我正在努力转换树状层次结构,下面是 class 层次结构的示例,如果有人能指出正确的方向,我将不胜感激。

我无法施法

var myobj2 = (IR<JB>)JR;

类:

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);
    }
}

为此,您的 IRule 界面需要协变。给定的示例 here 显示以下协方差:

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

这基本上就是您正在做的事情。所以在你的代码中你需要做的就是写

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

而不是

public interface IRule<T> { ... }

这使得您可以从 IRule<U> 转换为 IRule<V>,其中 UV 的子类(例如从 IRule<ShiftAction> 转换至 IRule<Job>).