我有一个实现接口的多个类。我想创建一个扩展方法来根据值过滤这些类的列表。这是一个假设的例子:
public enum Transmission
{
Standard = 1,
Automatic = 2
}
public interface ICar
{
Transmission Tranny { get; set; }
}
public class Car : ICar
{
public Transmission 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();
}
}
我想创建一个扩展方法来过滤汽车列表......但是这个方法并不适用于
var x = new List<Car>();
x.OnlyAuto <-- compile error...
扩展方法不是intellisense?
答案 0 :(得分:3)
问题并非特定于扩展方法。根据您的示例中的定义,以下结果会导致编译器错误:
void DoStuff(List<ICar> cars)
{
}
DoStuff(new List<Car>());
问题在于,即使List<Car>
实施ICar
List<Car>
类型的元素无法在预计会出现List<ICar>
的地方使用。
在示例中,您可以使用
var x = new List<ICar>();
x.OnlyAuto();
或添加以下扩展名方法:
public static IEnumerable<ICar> OnlyAuto(this IEnumerable<ICar> cars)
{
return cars.Where(x => x.Tranny == Transmission.Automatic).ToList();
}
并使用演员:
var x = new List<Car>();
(x.Cast<ICar>()).OnlyAuto();
如果你在google搜索“C#covariance”,你会发现很多人都写过这个问题。似乎在c#4.0中IEnumerable是协变的,这意味着你可以在上面的例子中消除Cast
的使用。