2012-01-28 3 views
5

저는 스택 오버플로에 newby입니다. 그래서 제발 쉽게가주세요! 나는 C#을 깊이 읽었지만, 나는 내가 믿을 수없는 시나리오를 보았습니다. 웹의 빠른 검색은 어떤 결과도 던지지 않았습니다. 나는 형식 인수를 지정하지 않고 AreEqual()를 호출 할 경우제네릭 메서드의 형식 인수에 대한 형식 유추

void AreEqual<T>(T expected, T actual) 

void AreEqual(object expected, object actual) 

:

AreEqual("Hello", "Hello") 

이 방법의 일반 또는 제네릭이 아닌 버전

를 호출

나는 다음과 같은 오버로드 된 메서드를 정의하는 말? 제네릭 메서드가 유추 된 형식 인수를 사용하여 호출 되었습니까? 아니면 메서드 인수가 System.Object으로 암시 적으로 캐스트 된 비 제너릭 메서드입니까?

제 질문에 대한 답변을 드리겠습니다. 어떤 조언을 주셔서 미리 감사드립니다.

+5

물론 이것을 확인하는 간단한 코드를 작성할 수 있습니다 ... –

+1

http://blogs.msdn.com/b/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx –

+0

@ 미치 밀 - 사실이긴하지만 첫 번째 게시물을 작성하지 않아도됩니다. 그리고 다른 사람들이 대답을보기에 유용합니다. – zekesteer

답변

5

제네릭은 함수 AreEqual(string, string)을 생성 할 수 있습니다. 이것은 AreEqual(object, object)보다 더 일치하므로 일반 함수가 선택됩니다.

흥미롭게도 컴파일러는 제약 조건 위반 오류가 발생하더라도이 일반 함수를 선택합니다. 이 예에서

봐는 :

using System.Diagnostics; 

namespace ConsoleSandbox 
{ 
    interface IBar 
    { 
    } 

    class Program 
    { 
     static void Foo<T>(T obj1) where T: IBar 
     { 
      Trace.WriteLine("Inside Foo<T>"); 
     } 


     static void Foo(object obj) 
     { 
      Trace.WriteLine("Inside Foo Object"); 
     } 

     static void Main(string[] args) 
     { 

      Foo("Hello"); 
     } 
    } 
} 

심지어 여기가 아닌 일반 버전을 통해 일반 버전을 선택합니다. 그리고 나서이 오류가 발생합니다 :

그러나 기능을 추가하면 Foo(string obj1)이 작동합니다.

+0

좋은 답변, 감사합니다! 좋은 예를 들자면, 그냥 확인해 보았습니다 :-) – zekesteer

+0

오버로드 확인은 .NET Framework가 아니라 C# 컴파일러에서 수행합니다. – phoog

+0

@phoog - 감사합니다. –