2012-05-05 4 views
4

솔직히 묻습니다 (이 질문의 일부분) here 하지만 지금은 다른 관련 질문이 있습니다.공분산은 콘크리트 유형보다 높습니까?

public class Base 
{ 
    public void Foo(IEnumerable<string> strings) { } 
} 

public class Child : Base 
{ 
    public void Foo(IEnumerable<object> objects) { } 
} 


List<string> lst = new List<string>(); 
lst.Add("aaa"); 
Child c = new Child(); 
c.Foo(lst); 

(N C# 3이 호출 : C# 4에 Base.Foo 그것이 호출 : Child.Foo)를

FW4에

임! 을 내가 c.Foo(lst); 쓸 때 -

모두 서명을 본다! (lst는 STRING의 IEnumerable입니다!), 공분산에 대한 모든 존경과

에 대해 이야기 할 수 있습니다 하지만 여전히 - IEnumerable<object> ??

콘크리트 유형 자체보다 공분산이 강합니까?

+0

서명을 지정하여 강제로 방법 중 하나를 선택할 수 있습니다. 'c.Foo ((IEnumerable ) lst)'상황에서 서명은 실제 구체적인 유형과 일치하지 않으므로 가정하지 않아야합니다. (아래의 대답은 3.0과는 다른 선택에 대한 이론적 근거를 제공하지만이 회색 영역에서는 캐스트로 동작을 명시 적으로 정의하는 것을 선호합니다) –

+0

@jamietre, 아니요, 작동하지 않습니다. 코드는 여전히'Child' 메소드를 호출 할 것입니다. – svick

+0

그럼 당신은 내 온 세상을 파괴했습니다! 물론입니다. 캐스트의 모호성을 제거하기 전에 "후보 방법 집합"이 축소 된 것처럼 보입니다. –

답변

5

이것은 공분산이 강하기 때문에가 아니라 C#이 "더 가까운"방법을 먼저 선택하기 때문입니다. 따라서 Child.Foo()을보고 적용 가능하다고 판단하고 (공분산 덕택에) Base.Foo()을 보지 않습니다.

여기에서는 특정 유형이 더 많이 "알고"있기 때문에 그 방법을 먼저 고려해야합니다.

후보 방법의 세트는 가장 유래 종류 만의 방법을 포함하도록 감소된다

: 세트의 각 방법 CF의 경우, C는이고

는 C# 4 스펙 §7.6.5.1보기 형식 F에서 선언 된 형식의 경우 기본 형식 C로 선언 된 모든 메서드가 집합에서 제거됩니다.

+0

그리고 기본 func를 원한다면? –

+0

그런 다음 캐스트를 사용해야합니다 : 변수 유형을 'Base'로 변경하거나 암시 적으로 : ((Base) c) .Foo (lst)'. – svick

+0

또는'Child' 내에서 호출하는 경우'base' 키워드를 사용할 수 있습니다 :'base.Foo (lst);' –

관련 문제