2011-04-13 151 views
4

我有一个类,我用来枚举我的数据库中的列表。数据库中的所有表都有自己的具有自己属性的类,它们都来自DatabaseTableRow。铸造IEnumerable <Derived> IEnumerable <BaseClass>

public class DatabaseLinkRowsEnumerator<T> : IEnumerator<T>, IEnumerable<T> where T : DatabaseTableRow 

我有一个用户类,它派生自派生自DatabaseTableRow的Page。然后我有一个属性返回一个DatabaseLinkRowsEnumerator,一个用户列表。

我也有一个UI函数,显示水平列表中的任何页面的列表,包括图像,名称和链接。

protected string GetVerticalListModuleHtml(IEnumerable<Page> pages) 

现在我想要做的就是将DatabaseLinkRowsEnumerator的值传递给此函数。用户从Page派生,DatabaseLinkRowsEnumerator是一个IEnumerator。即使在我尝试投射时,出现以下错误:

Unable to cast object of type 'Database.DatabaseLinkRowsEnumerator`1[Database.User]' to type 'System.Collections.Generic.IEnumerable`1[Database.Page]'. 

我正在使用ASP.NET 2.0。有没有人有任何想法如何转换/转换而不做每个副本?

回答

12

使用.NET 2.0,这是略有尴尬,但不要太用力:

public static IEnumerable<TBase> Cast<TDerived, TBase> 
    (IEnumerable<TDerived> source) 
    where TDerived : TBase 
{ 
    foreach (TDerived item in source) 
    { 
     yield return item; 
    } 
} 

这样称呼它:

IEnumerable<Page> pages = UtilityClass.Cast<User, Page>(users); 

这将懒洋洋地评价它。在LINQ更容易 - 您使用Cast扩展方法:

var baseSequence = derivedSequence.Cast<BaseClass>(); 

在.NET 4中,IEnumerable<T>是协在T所以有一个引用类型转换,从IEnumerable<DerivedClass>IEnumerable<BaseClass>已经:)

+0

如果继承设置正确,但在OP的帖子中,我确实没有看到DatabaseTableRow和Page之间的关系。 – 2011-04-13 20:02:25

+0

@Justin,OP说,Page派生自DatabaseTableRow – 2011-04-13 20:04:35

+0

虽然我在这里稍微有一点困惑,但是你会把这个方法放在哪里? – Connell 2011-04-13 20:17:35

4

你可以这样做:

DatabaseLinkRowsEnumerator<User> users = ... 
IEnumerable<Page> = users.Cast<Page>(); 

编辑:Cast扩展方法没有在.NET 2.0可用。相反,您可以将Jon Skeet的实现用作普通的静态方法。如果你使用的是VS2008,你也可以使用LinqBridge,它允许你在面向.NET 2.0时使用Linq到对象。

+0

是不是Enumerable.Cast <>()在.NET 3.5中引入的LINQ方法? – adamjford 2011-04-13 20:02:22

+1

@adamjford,是的,看我的编辑 – 2011-04-13 20:03:13

相关问题