c#泛型问题

时间:2010-06-14 10:30:47

标签: c# generics

谁能告诉我为什么这不起作用?我原本认为约束会使它有效。

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;}
    ....
}

2 个答案:

答案 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;