不要认为标题可以解释我的内容并且解释起来有点困难,所以我会让代码进行讨论。您可以将其复制+粘贴到LINQPad中并作为C#程序运行,或者在visual studio中作为常规c#项目进行必要的调整(例如:将调用转换为Dump()到Console.Writeline()等) -
请注意,如果您取消注释doStuff方法中的行,它将无法编译。
我的问题是,当generic2已经实现Iab<TA,TB>
时,为什么我需要演员?这是一些协方差的事吗?我还在使用.NET 3.5。
void Main()
{
doStuff<a,b>();
}
public void doStuff<TA, TB>()
where TA : class, Ia, new()
where TB : class, Ib, new()
{
Iab<TA, TB> x = null;
x = new generic1<TA, TB>();
x.Go().Dump();
//x = new generic2<TA>(); // <-Cannot implicitly convert type 'UserQuery.generic2<TA>' to 'UserQuery.Iab<TA,TB>'. An explicit conversion exists (are you missing a cast?)
x = (Iab<TA, TB>) new generic2<TA>();
x.Go().Dump();
}
public interface Ia
{}
public interface Ib
{}
public class a : Ia
{}
public class b : Ib
{}
public interface Iab<TA,TB>
where TA : class, Ia, new()
where TB : class, Ib, new()
{
string Go();
}
public class generic1<TA, TB> : Iab<TA,TB>
where TA : class, Ia, new()
where TB : class, Ib, new()
{
public string Go()
{
return "generic Base called";
}
}
public class generic2<TA> : Iab<TA,b>
where TA : class, Ia, new()
{
public string Go()
{
return "generic Sub called";
}
}
答案 0 :(得分:4)
我相信这是因为在编译时不知道一个或多个类型(在这种情况下,TS
)时,您将始终收到该错误。
编译器无法保证将使用兼容类型调用doStuff()
,因此它会强制您进行强制转换。
要了解编译器无法执行此操作的原因,请尝试按以下方式调用doStuff()
:
public class X: b {}
...
doStuff<a, X>(); // Compiles ok but:
未处理的异常:System.InvalidCastException:无法转换类型为'generic2
1[Demo.Program+X]' to type 'Iab
2 [Demo.Program + X,Demo.Program + Y]'的对象。
因此,您可以使用会导致崩溃的类型来调用它;编译器不会默默地让你这样做。