以下代码是我正在编写的程序的简单示例。
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();
}
}