谁能告诉我为什么这不起作用?我原本认为约束会使它有效。
public class ClassA<T> where T : ICommon
{
public ClassA()
{
ClassB b = new ClassB();
IEnumerable<T> alist = new List<T>;
b.Items = alist;
//Error: cannot convert from IEnumerable<T> to IEnumerable<ICommon>'
}
}
public class ClassB
{
public IEnumerable<ICommon> Items { get; set;}
....
}
答案 0 :(得分:12)
这可以在C#4中进行调整,但在C#3中不行。你要找的是泛型方差,自.NET 2.0以来CLR一直支持它,但不是在C#直到v4。
即使在C#4中,您也需要 约束T作为参考类型 - 因为协方差不适用于值类型。例如,即使List<int>
实现IEnumerable<IComparable>
,int
也无法转换为IComparable
。
稍微调整了一下你的代码(实际上有一些错别字),这可以用C#4编译器进行编译:
using System.Collections.Generic;
public interface ICommon {}
// Note the "class" part of the constraint
public class ClassA<T> where T : class, ICommon
{
public ClassA()
{
ClassB b = new ClassB();
IEnumerable<T> alist = new List<T>();
b.Items = alist;
}
}
public class ClassB
{
public IEnumerable<ICommon> Items { get; set;}
}
如果你被困在C#3和.NET 3.5中,另一种方法是使用Cast<T>()
:
b.Items = alist.Cast<ICommon>();
答案 1 :(得分:3)
这称为协方差(或者反对?我不确定),并且仅在C#4.0中工作。
您无法将IEnumerable<Common>
投射到IEnumerable<ICommon>
。 (当Common实现ICommon时。)
尝试使用
b.items = from f in alist select (T)f;