作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
引用这个在Visual Studio 2010 express中为C#编译的测试代码
public class Test
{
class Base { }
class Derived : Base { }
void Test1(IEnumerable<Derived> derived)
{
IEnumerable<Base> b = derived; //This works fine using covariance on IEnumerable
}
void Test2<TDerived, TBase>(TDerived derived) where TDerived : TBase
{
TBase b = derived; //This works fine because TDerived is constrained to derive from TBase
}
void Test3<TDerived, TBase>(IEnumerable<TDerived> derived) where TDerived : TBase
{
IEnumerable<TBase> b = derived; //ERROR: paraphrased: Cannot implicitly convert type IEnumerable<TDerived> to IEnumerable<TBase>
}
}
我正在尝试利用 IEnumerable 的协变性将泛型类型参数的可枚举存储在该类型参数被限制继承自的类的可枚举中。 Test3 就是例证。请注意,Test1 和 Test2(分别演示编译时类型的协方差和约束类型的分配)都可以正常编译。它是两种语言功能的组合,对我不起作用。
我可以使用 IEnumerable<TBase> b = derived.Cast<TBase>()
并 100% 确信如果我的理解没有缺陷,任何转换都不会失败,所以我确实有一个可用的解决方法。我的问题是,为什么编译器不允许这样做?这是否出于某些逻辑原因、编译器的疏忽或其他我没有想到的原因而被禁止?
最佳答案
初始问题的答案
您当前正在尝试将TDerived
类型的单个 元素转换为Base
类型的序列 .我也不希望你的 Cast
调用起作用,因为 TDerived
没有实现 IEnumerable
- 我怀疑你实际上已经做到了而是在不同的情况下工作。
我怀疑你实际上的意思是:
void Test3<TDerived>(IEnumerable<TDerived> derived) where TDerived : Base
{
IEnumerable<Base> b = derived;
}
编译没有问题。
已编辑问题的答案
好的,现在我们遇到了两个类型参数之间的真正的问题,问题是编译器不知道它们是引用类型——这是泛型变体所必需的。您可以使用 TDerived
上的 class
约束来解决此问题:
void Test3<TDerived, TBase>(IEnumerable<TDerived> derived)
where TDerived : class, TBase
{
IEnumerable<TBase> b = derived;
}
关于c# - 受约束泛型类型参数的逆变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18417639/
我是一名优秀的程序员,十分优秀!