2014-09-05 6 views
9

본문에서 인수 데이터 형식을 기반으로 다른 메서드를 호출하고 그 결과를 나중에 처리하는 C#에서 제네릭 메서드를 만들려고합니다. 나는 일반적인 래퍼 메서드를 생성하여이를 달성하려고 노력하고 있으며 특정 오버로드를 사용할 수없는 경우 사용할 일반 메서드를 포함하여 처리 메서드의 여러 오버로드를 제공합니다.C# : 일반 메서드가 특정 메서드 오버로드를 호출하지 않습니다.

처리 방법을 직접 호출하면 적절한 버전이 올바르게 선택됩니다. 그러나 래퍼 메서드에서 호출 할 때 전달 된 특정 데이터 형식에 대해 일치하는 오버로드가 있더라도 항상 일반 메서드를 선택합니다.

내가 원하는 방식으로 동작하도록 코드를 조정할 수있는 방법이 있습니까? 아니면 다른 접근법을 사용해야합니까?

Mono 2.6과 호환되도록 코드가 필요합니다. 이 동작 올바른 방법이

using System; 

class Program 
{ 
    static void Func<T>(T val) 
    { 
     Console.WriteLine("Generic Func"); 
    } 

    static void Func(int val) 
    { 
     Console.WriteLine("Int Func"); 
    } 

    static void Func(string val) 
    { 
     Console.WriteLine("String Func"); 
    } 

    static void FuncWrap<T>(T val) 
    { 
     Console.Write("Wrap: "); 
     Func(val); 
    } 

    static void Main(string[] args) 
    { 
     Func(2); 
     Func("Potato"); 
     Func(2.0); 

     FuncWrap(2); 
     FuncWrap("Potato"); 
     FuncWrap(2.0); 

     Console.Read(); 
    } 
} 
+0

당신은 int와 문자열을 취하는 FuncWrap 오버로드를 가질 수 있습니다 (또는 Func 메서드를 직접 랩핑하지 않고 사용하면됩니다). –

답변

13

있습니까?

이미 C# 언어 사양에 따라 올바른 동작입니다. FuncWrap 내에서 호출되는 Func의 오버로드는 보통 컴파일시 일 때 으로 결정되므로 실행 시간 유형에 따라 다른 Func 오버로드를 선택할 수 없습니다.

static void FuncWrap<T>(T val) 
{ 
    Console.Write("Wrap: "); 
    dynamic x = val; 
    Func(x); 
} 

지금 x 값의 실제 타입에 기초하여 실행 시간에 오버 확인을 수행한다 : 동작 변경

한가지 방법은, 그러나 동적 인 입력을 사용하는 것이다. 이로 인해 성능 비용이 발생하지만 원하는대로 수행해야합니다. 하지만 분명 꽤 끔찍한

static void FuncWrap<T>(T val) 
{ 
    Console.Write("Wrap: "); 
    if (typeof(T) == typeof(string)) 
    { 
     Func((string)(object)val); 
    } 
    else if (typeof(T) == typeof(int)) 
    { 
     Func((int)(object)val); 
    } 
    else 
    { 
     Func(val); 
    } 
} 

:

다른 방법으로는 오버로드의 하드 코딩 지식이 없습니다.

+0

죄송합니다. 정확하게 말하지 않았습니다. 나는 그것이 올바른 방식으로 행동하는 것처럼 "올바른"것을 의미했습니다. Dynamo가 Mono 2.6에서 작동하지 않는 것 같습니다 (Unity 엔진에서 코드를 사용하고 있습니다). 두 번째 방법은 바람직하지 않습니다. 나는 더 깨끗한 (그리고 이상적으로 더 빠른) 것을 찾고 있습니다. –

+0

@TomFrooxiusMariank : Mono 2.6의 릴리즈 노트를 보면 * 지원되어야합니다 - Unity가 실제로 이전 프로파일로 제한하는 것일 수도 있습니다. (.NET 4 프로파일이 필요합니다.) '동적 인'이 없다면 아마 내 대답의 마지막 부분에서 해킹을하는 것이 가장 좋을 것입니다 ... 그것은 동적으로보다 잘 수행 될 것입니다. 반사). 당연히 리플렉션을 사용할 수도 있지만 그렇게 빠르지는 않을 것입니다. 이들 중 어느 것도 적합하지 않다면 재 설계를 고려해야합니다. –

+0

필자는 Unity의 현재 유니티 버전과는 운이 좋지 않을 것입니다. 필자는 프로파일을 어떻게 든 바꿀 수 있는지를 점검 할 것입니다. 그러나 그것이 원하지 않는 결과를 가져올 지 확신 할 수 없습니다. 작동하지 않으면이 기능이 필요하지 않도록 코드를 재 작업 할 것입니다. 도움 주셔서 감사합니다. –

관련 문제