开发者

Extension method to filter a list of concrete types based on interface?

I have a multiple classes that implement an interface. I want to create an extension method to filter a list of these classes based on a value. Here's a hypothetical example:

public enum Transmission
{ 
    Standard = 1,
    Automatic = 2
}

public interface ICar
{
    Transmission Tranny { get; set; }
}

public class Car : ICar
{
    public Tra开发者_如何学Cnsmission Tranny { get; set; }
    public string Make { get;set;}
}

public static class CarExtensions
{
    public static List<ICar> OnlyAuto(this List<ICar> cars)
    {
        return cars.Where(x => x.Tranny == Transmission.Automatic).ToList();
    }
}

I want to create an extension method to filter a list of cars...but this one doesn't kick in for

var x = new List<Car>();
x.OnlyAuto <-- compile error...

the extension method doesn't intellisense?


The problem isn't specific to extension methods. Given the definitions from your example the following results in a compiler-error:

void DoStuff(List<ICar> cars)
{
}

DoStuff(new List<Car>());

The problem is that even though the elements of the List<Car> implement ICar the type List<Car> cannot be used in places where a List<ICar> is expected.

In the example you could use

var x = new List<ICar>(); 
x.OnlyAuto();

or add the following extension-method:

public static IEnumerable<ICar> OnlyAuto(this IEnumerable<ICar> cars)
{
   return cars.Where(x => x.Tranny == Transmission.Automatic).ToList();
}

and use Cast:

var x = new List<Car>();
(x.Cast<ICar>()).OnlyAuto();

If you search google for "C# covariance" you will find that a lot of people has written about this problem. And it seems that in c# 4.0 IEnumerable is covariant, meaning that you can eliminate the use of Cast in the example above.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜