2011-04-06 2 views
1

C#의 확장 메서드 동작에 대해 궁금합니다. 아래 예제를 참조하십시오 :C# 확장 메서드가 예상대로 작동하지 않습니다. - 예를 참조하십시오.

static string ExtendedToString(this object oObj) 
{ 
    return "Object"; 
} 

static string ExtendedToString(this Array oArray) 
{ 
    return "Array"; 
} 

// Example 1: int array - working as expected. 
int[] o = new int[] { 1, 2, 3 }; 
o.ExtendedToString(); // returns "Array" 

// Example 2: array as object - did not expect the result. 
object o = new int[] { 1, 2, 3 }; 
o.ExtendedToString(); // returns "Object" 

int []의 오브젝트 확장 메서드가 호출 된 이유는 무엇입니까 (마지막 경우)?

object o = new int[] { 1, 2, 3 }; 

그게 이유 : 당신이

int[] obj = o as int[]; 
obj.ExtendedToString(); // returns "Array" 

해상도가 (정적)에 따라대로가

를 입력 할 수 있습니다

o.ExtendedToString(); // returns "Object" 

하지만 객체로 O를

답변

9

과부하 해결 이온은 컴파일 타임에 수행됩니다. 컴파일러에서는 oobject으로 선언되므로 object이 걸리는 오버로드를 호출합니다. o이 런타임에 실제로 배열을 포함한다는 사실은 컴파일러가 알지 못하기 때문에 무의미합니다. 실제로 확장 방법에 국한되지이다

, 당신은 보통의 정적 메소드 (ExtensionsClass.ExtendedToString(o)) 때문에 정적 타이핑의

+0

의미가 있습니다. 과부하가 걸리는 가상의 방법처럼 보이기 때문에 이상한 것입니다.하지만 그렇지 않습니다. 그것은 혼란스러운 부분이었습니다. 감사. – Krumelur

+0

@Krumelur, 그냥 확장 메서드가 정적 메서드를 호출하는 구문 설탕이라는 것을 명심하십시오. –

+0

맞아요. 그것이 내가 의미하는 바입니다. 그것들을 사용할 때 그들은 정적과 같은 것을 보지 않습니다. – Krumelur

1

당신은 선언
1

로 호출하여 동일한 결과를 얻을 것입니다. 확장 메서드는 일반 구문으로 호출 한 것처럼 컴파일러에서 다시 작성됩니다. 컴파일시 두 번째 객체 o는 Object 유형이므로 객체의 확장 메서드는

0

입니다. Thomas Levesque는 코드가 작동하지 않는 이유에 대한 완벽한 설명을 이미 가지고 있으므로 반복하지 않겠습니다. 주변 is 또는 as과 런타임에 테스트하고 작업 :

static string ExtendedToString(this object oObj) 
{ 
    if(oObj is Array) 
     return "Array"; 
    else 
     return "Object"; 
} 

는 일반적으로 같은 방식으로 테스트를 입력 안티 - 패턴의 비트이며, 가능하면 당신은 가상 방법을 선호한다. 그러나이 경우 Array/Object 클래스를 변경할 수 없기 때문에 여전히 최상의 솔루션 일 것입니다.

특별한 치료가 필요한 많은 수업이있는 경우 Type ->Func<object,string> 사전을 고려해 볼 수 있습니다.

관련 문제