Ben*_*Laz 115 c# covariance contravariance
我无法理解为什么以下C#代码无法编译.
正如您所看到的,我有一个静态泛型方法Something with a IEnumerable<T>
parameter(并且T
被约束为一个IA
接口),并且此参数不能隐式转换为IEnumerable<IA>
.
解释是什么?(我不寻找解决方法,只是为了解它为什么不起作用).
public interface IA { }
public interface IB : IA { }
public class CIA : IA { }
public class CIAD : CIA { }
public class CIB : IB { }
public class CIBD : CIB { }
public static class Test
{
public static IList<T> Something<T>(IEnumerable<T> foo) where T : IA
{
var bar = foo.ToList();
// All those calls are legal
Something2(new List<IA>());
Something2(new List<IB>());
Something2(new List<CIA>());
Something2(new List<CIAD>());
Something2(new List<CIB>());
Something2(new List<CIBD>());
Something2(bar.Cast<IA>());
// This call is illegal
Something2(bar);
return bar;
}
private static void Something2(IEnumerable<IA> foo)
{
}
}
Run Code Online (Sandbox Code Playgroud)
错误我Something2(bar)
排队:
参数1:无法从'System.Collections.Generic.List'转换为'System.Collections.Generic.IEnumerable'
Eri*_*ert 218
错误信息信息不足,这是我的错.对于那个很抱歉.
您遇到的问题是协方差仅适用于引用类型的结果.
你现在可能正在说"但是它IA
是一种参考类型".是的.但你没有说这T
等于 IA
.你说的T
是哪一种类型的实现 IA
,和值类型可以实现一个接口.因此,我们不知道协方差是否有效,我们不允许它.
如果你想要协方差工作,你必须告诉编译器类型参数是带有class
约束的参考类型以及IA
接口约束.
错误信息确实应该说转换是不可能的,因为协方差需要保证引用类型,因为这是根本问题.
Mar*_*oth 26
我只是想用一些代码示例来补充Eric的优秀内部答案,这些代码示例可能不熟悉泛型约束.
改变这样Something
的签名:class
约束必须先行.
public static IList<T> Something<T>(IEnumerable<T> foo) where T : class, IA
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5197 次 |
最近记录: |