2014-09-05 7 views
3

.NET Framework에는 메서드에 대한 오버로드가 여러 개 있으며 그 중 일부는 특정 개수의 매개 변수를 사용하여 마지막 "catch" 모두 "params 키워드가 사용됩니다. 이것의 일반적인 예로는 나는이 방법 과부하의 많은 존재 이유에 대한 특별한 이유가 있는지 궁금 해서요 String 클래스 예컨대 :C에서 특정 인수와 params 메서드 오버로드를 모두 갖는 이점 C#

에있다? 처음에는 그것이 공연과 관련이있을 것이라고 생각했습니다. 이 질문에 대한 질문과 대답은 Cost of using params in C#입니다.

그러나 Reference Source 웹 사이트를 사용하여. NET 소스 코드에 대해 알아보기 시작했습니다. String class source code에서 이것을 알아 냈습니다 :

String.Concat()은 실제로 사용되는 고정 인수의 수에 따라 다른 코드가 실행됩니다. 이것은 내 마음에 확실히 최적화 될 것입니다.

public static String Format(String format, Object arg0) 
{ 
    return Format(format, new Object[] { arg0 }); 
} 

public static String Format(String format, Object arg0, Object arg1) 
{ 
    return Format(format, new Object[] { arg0, arg1 }); 
} 

public static String Format(String format, Object arg0, Object arg1, Object arg2) 
{ 
    return Format(format, new Object[] { arg0, arg1, arg2 }); 
} 

public static String Format(String format, params Object[] args) 
{ 
    // Do work here... 
} 

그래서 성능 이점이 있습니다 또는이 단순히 편의상의 문제 일 수있다, 아니면 둘 다 다음 부연 코드를 아래 참조 - String.Format() 그러나 단지 주요 param 방법 래퍼를 제공하는 것? 위의 특별한 경우에는 분명한 이점이 없으며 단지 작업을 복제하는 것처럼 보입니다.

+0

각 호출자에 IL의 몇 바이트를 저장하므로 배열을 할당하고 초기화 할 필요가 없습니다. –

+0

@MichaelLiu 그러나 * 여기에 배열을 할당하고 초기화하는 중입니다. 외부의 대신에 새로운 방법으로 수행합니다. – Servy

+0

@Servy : 각 호출자에 IL의 몇 바이트를 저장합니다. 즉, 각 호출 사이트에서 컴파일러는 인수를 푸시하기위한 지시 만 내 보내면됩니다. 전용 과부하가 없으면 컴파일러는 배열을 할당하고 초기화하는 명령을 내 보내야합니다. –

답변

1

업데이트 : String.Concat이 아니라 String.Format입니다.

나는 모든 호출이 StringBuilder.AppendFormat로 끝나고 매우 복잡하며 입력 인수의 수를 다른 방식으로 처리하는 경우 코드 중복의 주요 원인이 될 것이라고 생각합니다.

매개 변수 오버로드를 통해 메서드를 호출하는 오버 헤드가 매우 중요한 강력한 API (예 : 추적)가 있다면 상황이 다릅니다. 최대 5의 인수가 될 수 있습니다. LINQ와 공통적 인 암시 적 대리자 할당에도 동일하게 적용됩니다. 이러한 임시 위임 인스턴스는 최적화 된 코드에서 저렴하지 않습니다. 예를 들어 Roslyn은 암시 적 대리자 할당 비용 때문에 LINQ 사용을 금지했습니다.

+0

실제로 각기 다른 과부하를 구현하기에는 너무 많은 작업이 있었다면 과부하를 시작하지 않는 것이 어떻겠습니까? – Servy

+0

이미 모든 오버로드를 제공하면 나중에 누군가가 훌륭한 아이디어를 내면 구현을 변경할 수 있습니다. 나중에 이러한 오버로드를 제공하려면 향상된 오버로드를 사용하기 위해 모든 응용 프로그램을 다시 컴파일해야합니다. –

+0

감사합니다 @AloisKraus, 이것이 제가 가장 기대하는 대답 인 것 같습니다. 왜 params가 더 나빠지는지 설명해 주시겠습니까? 예 : String.Format ("{0}, {1}", 1, 2) 및 String.Format ("{0}, {1}", 새 객체 [] {1, 2}) '정확히 똑같습니까? 아니면이 호출에도 차이가 있습니까? –

2

그것은 당신이 그 메소드를 호출하는 서명 각각의 대의원을 만들 수 있습니다 :

Func<string, object, object> foo = string.Format; 

이것은 params 방법으로 작동하지 않을 것입니다; 해당 오버로드를 Func<string, object[]> 또는 해당 서명에 params을 제공 한 대리인에게만 할당 할 수 있습니다. params 오버로드를 호출하여 (아마도 람다를 사용하여) 예제에서 사용 된 서명의 위임을 생성하는 새로운 메서드를 만들어야합니다.

+0

전용 과부하로 인해 이런 일이 가능하지만, .NET 팀이이 특별한 경우에 전용 과부하를 생성 한 실제 이유는 의심 스럽습니다. –

+0

@MichaelLiu 동의. – Servy

+0

'params' 키워드로 인해 델리게이트 생성이 중단됩니까? 나는 단지'Func '와 같을 것이라고 가정했을 것입니다. – DavidG