I have a class which I use to enumerate through lists from my database. All tables in the database have their own class with their own properties, and they all derive from DatabaseTableRow.
public class DatabaseLinkRowsEnumerator<T> : IEnumerator<T>, IEnumerable<T> where T : DatabaseTableRow
I have a User class, which derives from Page, which derives from DatabaseTableRow. I then have a property that returns a DatabaseLinkRowsEnumerator, a list of users.
I also have a UI function that displays lists of any Page in a horizontal list, with the image, name and a link.
protected string GetVerticalListModuleHtml(IEnumerable<Page> pages)
Now all I want to do is pass the value I have of DatabaseLinkRowsEnumerator to this function. User derives from Page, and DatabaseLinkRowsEnumerator is an IEnumerator. Even when I try to cast, 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'm using ASP.NET 2.0. Does anyone have any ideas of how to cast/convert this without making an entire copy of each?
To cast an IEnumerable to an IEnumerable<T>, you can use this code: C#. Copy Code. IEnumerable ienumerable = new int [] { 1, 5, 6, 7, 8, 11, 10, 134, 90 }; IEnumerable casted = ienumerable.Cast<int> (); // change 'int' into the //type of the elements in your IEnumerable. Now, you can use a LINQ query for casted.
An IEnumerable<T> that contains each element of the source sequence cast to the specified type. source is null. An element in the sequence cannot be cast to type TResult. The following code example demonstrates how to use Cast<TResult> (IEnumerable) to enable the use of the standard query operators on an ArrayList.
But for an IEnumerable, you can't use LINQ. If you write this LINQ query for an IEnumerable: Then, you get this error: Could not find an implementation of the query pattern for source type 'System.Collections.IEnumerable'. 'Where' not found. Consider explicitly specifying the type of the range variable 'i'.
For example, ArrayList does not implement IEnumerable<T>, but by calling Cast<TResult> (IEnumerable) on the ArrayList object, the standard query operators can then be used to query the sequence. If an element cannot be converted to type TResult, this method throws a InvalidCastException.
Using .NET 2.0, it's slightly awkward, but not too hard:
public static IEnumerable<TBase> Cast<TDerived, TBase>
(IEnumerable<TDerived> source)
where TDerived : TBase
{
foreach (TDerived item in source)
{
yield return item;
}
}
Call it like this:
IEnumerable<Page> pages = UtilityClass.Cast<User, Page>(users);
This will evaluate it lazily. In LINQ it's easier - you use the Cast
extension method:
var baseSequence = derivedSequence.Cast<BaseClass>();
In .NET 4, IEnumerable<T>
is covariant in T
so there's a reference type conversion from IEnumerable<DerivedClass>
to IEnumerable<BaseClass>
already :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With