2009-07-15 73 views
3

我有以下继承:这个通用演员为什么会失败?

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]

而且为什么我要投它呢?

+0

这种类型的演员将在C#4.0中得到支持,将在今年晚些时候发布。解决此问题的功能称为协变通用参数。 – 2009-07-15 19:19:23

回答

16

你需要转换,因为IEnumerable<T>没有在T.协变你可以这样做:

return result.Cast<TeraRow>(); 
+0

向下转换泛型类型列表...泛型在没有显式定义复合接口的情况下崩溃的少数几个地方之一。 – 2009-07-15 19:16:07

0

如果您需要铸造列表像原始参考一样执行(在索引处设置项目还会在原始集合中设置项目,则可以创建一个包装类,以实现IList <T>(除非我失去了一些东西),对于通用的解决方案,你会需要两个由于通用的限制限制:

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 <T>,那么您可以使用前面提到的扩展方法的Cast <T>。