Why can't I use LINQ for objects when my class repeatedly runs IEnumerable <T>?
I have an interesting problem when a class inherits a class that implements IEnumerable, but I also want the class to implement IEnumerable for another type. Everything works, except for IEnumerable extension methods, which means that I cannot use LINQ for objects by default without having the first. Does anyone have any ideas besides permanent casting?
using System; using System.Collections.Generic; using System.Linq; namespace LinqTesting { public class Trucks<T> : Vehicles, IEnumerable<Truck> { public Trucks() { // Does Compile var a = ((IEnumerable<Truck>)this).FirstOrDefault(); // Doesn't Compile, Linq.FirstOrDefault not found var b = this.FirstOrDefault(); } public new IEnumerator<Truck> GetEnumerator() { throw new NotImplementedException(); } } public class Vehicles : IEnumerable<Vehicle> { public IEnumerator<Vehicle> GetEnumerator() { throw new NotImplementedException(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw new NotImplementedException(); } } public class Vehicle { } public class Truck : Vehicle { } } Actually, you can, but you cannot take advantage of generic type inference, because your class implements two IEnumerable<T> two different types, and the compiler cannot know which type you want to use.
You can specify it direclty, for example:
var b = this.FirstOrDefault<Truck>(); Change your code to:
public class Trucks : Vehicles<Truck> { } public class Vehicles<T> : IEnumerable<T> where T : Vehicle { } public class Vehicle { } public class Truck : Vehicle { } The implementation of IEnumerable confuses the compiler several times, which IEnumerable <> must be considered for this.
IEnumerable<Vehicle> or IEnumerable<Truck>? this.FirstOrDefault<Truck>() might compile. It looks like you're stuck. It is suggested here to reduce your typing. You can create an extension method for some of your commonly used IEnumerable <> types.
var a = myList.AsTruckEnumerable().FirstOrDefault(); public static partial class Extensions { public static IEnumerable<Truck> AsTruckEnumerable (this IEnumerable<Truck> trucks) { return trucks; } } public class Trucks<T> : Vehicles, IEnumerable<Truck> { public Trucks() { // Does Compile var a = ((IEnumerable<Truck>)this).FirstOrDefault(); // Does compile var b = this.AsTruckEnumerable().FirstOrDefault(); // Doesn't Compile, Linq.FirstOrDefault not found //var b = this.FirstOrDefault(); } public new IEnumerator<Truck> GetEnumerator() { throw new NotImplementedException(); } } public new IEnumerator GetEnumerator ()
This new keyword on this line hides the GetEnumerator () method inherited from the Vehicle class. I'm not sure if this will work, but perhaps instead of explicitly implementing the interface .