Casting IEnumerable <Derived> to IEnumerable <BaseClass>

I have a class that I use to list in lists from my database. All tables in the database have their own class with their own properties, and they all come from DatabaseTableRow.

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

I have a User class that comes from a page that comes from DatabaseTableRow. Then I have a property that returns DatabaseLinkRowsEnumerator, a list of users.

I also have a user interface function that displays lists of any page in a horizontal list with an image, name and link.

 protected string GetVerticalListModuleHtml(IEnumerable<Page> pages) 

Now all I want to do is pass the value that I have DatabaseLinkRowsEnumerator for this function. The user is logged out of the page, and DatabaseLinkRowsEnumerator is IEnumerator. Even when I try to start, I get the following error:

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

I am using ASP.NET 2.0. Does anyone have any ideas on how to cast / convert this without making a whole copy of each?

+4
source share
2 answers

Using .NET 2.0, this is a bit inconvenient, but not too complicated:

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

Name it as follows:

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

This will evaluate him lazily. In LINQ, this is simpler - you use the Cast extension method:

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

In .NET 4, IEnumerable<T> is covariant in T , so there is a reference type conversion from IEnumerable<DerivedClass> to IEnumerable<BaseClass> already :)

+12
source

You can do it:

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

EDIT: Cast extension method is not available in .NET 2.0. Instead, you can use the Jon Skeet implementation as a regular static method. If you are using VS2008, you can also use LinqBridge , which allows you to use Linq for objects when you configure .NET 2.0

+4
source

Source: https://habr.com/ru/post/1347976/


All Articles