以下代码是我正在编写的程序的简单示例。

public class Y
{ }

public class X : Y
{ }

public class W : Y
{ }

public interface IAaa<T>
    where T : Y
{
    void Execute(T ppp);
}

public abstract class Aaa<T> : IAaa<T>
    where T : Y
{
    public abstract void Execute(T ppp);
}

public class Bbb : Aaa<X>
{
    public override void Execute(X ppp)
    { }
}

public class Ccc : Aaa<W>
{
    public override void Execute(W ppp)
    { }
}

public class Factory
{
    public static IAaa<Y> Get(bool b)
    {
        if(b)
            return new Bbb();
        else
            return new Ccc();
    }
}

class Program
{
    static void Main(string[] args)
    {
        IAaa<Y> aa;
        aa = Factory.Get(true);
    }
}


当我编译它时,出现以下错误


  错误CS0266:无法隐式转换类型'ConsoleApplication3.Bbb'
  到“ ConsoleApplication3.IAaa”。一个明确的
  转换存在(您是否缺少演员表?)
  
  错误CS0266:无法隐式转换类型'ConsoleApplication3.Ccc'
  到“ ConsoleApplication3.IAaa”。一个明确的
  转换存在(您是否缺少演员表?)


有什么办法可以使其工作?

最佳答案

您不能以尝试的方式使用该界面。查找covariance/contravariance,您正在尝试做与可能的相反的操作(您可能在接口中使用<in T>,但您正在尝试像<out T>那样使用它)。

以类Bbb为例-它具有一个Execute(X)方法。如果您尝试传递Y(可能是X也可能不是IAaa)该怎么办?编译器不允许这样做,因为您从未在代码中定义过那种情况。

您可以通过创建和实现另一个接口来执行所需的操作。例如。

public interface IAaa
{
    void Execute(Y ppp);
}


也许是这样实现的,因此,如果尝试使用无效类型调用它,则会引发强制转换异常:

void Main()
{
        IAaa aa;
        aa = Factory.Get(true);
}

public class Y
{ }

public class X : Y
{ }

public class W : Y
{ }

public interface IAaa<T> : IAaa
    where T : Y
{
    void Execute(T ppp);
}

public interface IAaa
{
    void Execute(Y ppp);
}

public abstract class Aaa<T> : IAaa<T>
    where T : Y
{
    public abstract void Execute(T ppp);
    void IAaa.Execute(Y ppp)
    {
        this.Execute(ppp);
    }
    protected abstract void Execute(Y ppp);
}

public class Bbb : Aaa<X>
{
    public override void Execute(X ppp)
    { }
    protected override void Execute(Y ppp)
    {
        this.Execute((X)ppp);
    }
}

public class Ccc : Aaa<W>
{
    public override void Execute(W ppp)
    { }
    protected override void Execute(Y ppp)
    {
        this.Execute((W)ppp);
    }
}

public class Factory
{
    public static IAaa Get(bool b)
    {
        if(b)
            return new Bbb();
        else
            return new Ccc();
    }
}

09-30 16:38