2010-02-24 2 views
1

인터페이스를 구현하는 여러 클래스가 있습니다. 값에 따라 이러한 클래스 목록을 필터링하는 확장 메서드를 만들려고합니다. 여기에 가상의 예입니다 :인터페이스를 기반으로하는 구체적인 유형의 목록을 필터링하는 확장 방법은 무엇입니까?

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... 

에 대한 걷어차하지 않습니다 인텔리 센스?

답변

2

문제는 확장 방법과 관련이 없습니다. 컴파일러 오류에 다음과 같은 결과 귀하의 예제에서 정의를 감안할 때 :

void DoStuff(List<ICar> cars) 
{ 
} 

DoStuff(new List<Car>()); 

문제는 List<Car>의 요소는 타입 List<Car>List<ICar>이 예상되는 장소에서 사용할 수 없습니다 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(); 

을 당신은 "C#을 위해 구글을 검색하는 경우 공분산 "을 사용하면 많은 사람들이이 문제에 관해 썼다는 것을 알 수 있습니다. 그리고 그것은 C# 4.0에서 IEnumerable이 공변 (covariant)되어있는 것으로 보입니다. 위의 예에서 Cast의 사용을 제거 할 수 있다는 의미입니다.

관련 문제