2014-09-05 133 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和string的FuncWrap重載(或者直接使用Func方法直接不包裝)。 – 2014-09-05 12:20:57

回答

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

對不起,我沒有正確地說出來。我的意思是「正確的」,因爲它會按照我需要的方式行事。 動態似乎不適用於Mono 2.6(我在Unity引擎中使用代碼)。 是的,第二種方法是不可取的,我正在尋找更乾淨的東西(並且理想的更快)。 – 2014-09-05 12:10:33

+0

@TomFrooxiusMariank:查看Mono 2.6的發行說明,應*支持*它可能是Unity實際上限制了一些舊的配置文件。 (它需要.NET 4配置文件。)如果沒有'dynamic',你可能會在我的答案結束時使用黑客最好的解決方案......這樣做表現會相當好(比動態更好,這基本上是使用反射)。你當然可以使用反射,但這不會很快。如果這些都不合適,你應該考慮重新設計。 – 2014-09-05 12:13:49

+0

我明白了,我現在可能不太會用目前的Unity版本的Unity,但我會檢查是否可以以某種方式更改配置文件,但我不確定這是否會導致不希望的後果。 如果它不起作用,我可能會重新編寫代碼以避免使用此功能。 感謝您的幫助。 – 2014-09-05 12:17:46