Con*_*ell 4 c# generics inheritance casting .net-2.0
我有一个类,我用它来枚举我的数据库中的列表.数据库中的所有表都有自己的类,它们都有自己的属性,它们都来自DatabaseTableRow.
public class DatabaseLinkRowsEnumerator<T> : IEnumerator<T>, IEnumerable<T> where T : DatabaseTableRow
Run Code Online (Sandbox Code Playgroud)
我有一个User类,它派生自Page,它派生自DatabaseTableRow.然后我有一个属性返回DatabaseLinkRowsEnumerator,一个用户列表.
我还有一个UI功能,可以显示水平列表中任何页面的列表,包括图像,名称和链接.
protected string GetVerticalListModuleHtml(IEnumerable<Page> pages)
Run Code Online (Sandbox Code Playgroud)
现在我想要做的就是将DatabaseLinkRowsEnumerator的值传递给这个函数.用户派生自Page,DatabaseLinkRowsEnumerator是IEnumerator.即使我尝试施放,我也会收到以下错误:
Unable to cast object of type 'Database.DatabaseLinkRowsEnumerator`1[Database.User]' to type 'System.Collections.Generic.IEnumerable`1[Database.Page]'.
Run Code Online (Sandbox Code Playgroud)
我正在使用ASP.NET 2.0.有没有人有任何想法如何投射/转换这个没有制作每个的完整副本?
Jon*_*eet 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;
}
}
Run Code Online (Sandbox Code Playgroud)
像这样称呼它:
IEnumerable<Page> pages = UtilityClass.Cast<User, Page>(users);
Run Code Online (Sandbox Code Playgroud)
这将懒洋洋地评估它.在LINQ中,它更容易 - 您使用Cast扩展方法:
var baseSequence = derivedSequence.Cast<BaseClass>();
Run Code Online (Sandbox Code Playgroud)
在.NET 4中,IEnumerable<T>是协变的T所以有一个引用类型转换IEnumerable<DerivedClass>到IEnumerable<BaseClass>已经:)
你可以这样做:
DatabaseLinkRowsEnumerator<User> users = ...
IEnumerable<Page> = users.Cast<Page>();
Run Code Online (Sandbox Code Playgroud)
编辑:Cast扩展方法在 .NET 2.0 中不可用。您可以将 Jon Skeet 的实现用作普通的静态方法。如果您使用的是 VS2008,您还可以使用LinqBridge,它允许您在面向 .NET 2.0 时使用 Linq to Objects