我有一个类用于枚举数据库中的列表。数据库中的所有表都有自己的类,它们都有自己的属性,它们都来自DatabaseTableRow。
public class DatabaseLinkRowsEnumerator<T> : IEnumerator<T>, IEnumerable<T> where T : DatabaseTableRow
我有一个User类,它派生自Page,它派生自DatabaseTableRow。然后我有一个属性,它返回一个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。有没有人有任何关于如何转换/转换它的想法而不制作每个的完整副本?
答案 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>
的引用类型转换:)
答案 1 :(得分:4)
你可以这样做:
DatabaseLinkRowsEnumerator<User> users = ...
IEnumerable<Page> = users.Cast<Page>();
编辑:{2.0}中没有Cast
扩展方法。您可以将Jon Skeet的实现用作常规静态方法。如果你正在使用VS2008,你也可以使用LinqBridge,它允许你在定位.NET 2.0时使用Linq到对象