为什么这个通用演员会失败?

时间:2009-07-15 19:12:42

标签: .net generics casting ienumerable

我有以下继承:

internal abstract class TeraRow{}

internal class xRow : TeraRow {} // xRow is a child of TeraRow

public IEnumerable<TeraRow> Compare(MappedTables which, DateTime selectionStart
        , DateTime selectionEnd, string pwd)
{
    IEnumerable<xRow> result=CompareX();
    return  (IEnumerable<TeraRow>)result; //Invalid Cast Exception? 

}

无法转换类型为'System.Collections.Generic.List 1[xRow]' to type 'System.Collections.Generic.IEnumerable的对象1 [TeraRow]

另外,为什么我需要施放它?

4 个答案:

答案 0 :(得分:17)

你需要施放它,因为IEnumerable<T>在T上不协变你可以这样做:

return result.Cast<TeraRow>();

答案 1 :(得分:2)

请参阅此问题:.NET Casting Generic List

答案 2 :(得分:1)

你正在违反逆转。你需要c#4.0才能工作。 IEnumerable类型无法在2.0到3.5中交换IEnumerable。关于它的msdn文章是http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx

答案 3 :(得分:0)

如果您需要像原始引用一样执行转换列表(在索引处设置项目也会设置原始集合中的项目,您可以创建一个实现IList&lt; T&gt;的包装类。“除非我遗漏某些内容),对于通用解决方案,由于通用约束限制,您需要两个:

public class UpCastList<FromType, ToType> : IList<ToType>
    where FromType : ToType

public class DownCastList<FromType, ToType : IList<ToType>
    where ToType : FromType

另一种可能性是委派转换:

public class CastList<FromType, ToType> : IList<ToType>
{
    public CastList(IList<FromType> source, Func<FromType, ToType> converter) { ... }
}

编辑:如果您只需要一个IEnumerable&lt; T&gt;,那么您可以使用Cast&lt; T&gt;如前所述的扩展方法。