2010-07-23 52 views
5

的。如果我有如下的類:2的方法,使用2個泛型類型相同

class MyClass<T,U> 
{ 
    public void DoSomething(T t) 
    { 
    } 

    public void DoSomething(U u) 
    { 
    } 
} 

但使用相同類型(new MyClass<int,int>()) 編譯沒有建造它,但如果我嘗試調用DoSomething它的錯誤因爲一個模糊的電話,這當然是正確的。但是如果該方法是通過反射或其他動態方式來調用的話。我想它會在運行時拋出異常。所以我的問題是爲什麼編譯器允許我使用相同的類型創建這個類,如果有異常等待發生?

+0

感謝所有的答覆。你們中的一些人已經說過不同的方法,這顯然是最好的解決方案。順便說一句,我最初注意到這種情況不是用方法,而是用索引(this [T t]和this [U u]),所以不可能重命名這些方法。我現在已經改變了設計,所以原來的問題仍然無法解決,但問題可能仍然是人們感興趣的:) – RichK 2010-07-23 13:13:12

回答

4

編譯器關心的是實際的歧義,並沒有強調任何與重載泛型方法有關的歧義。

如果你不想讓這個,可惜沒有辦法添加一個泛型類型約束,即where T != U,所以你需要只是拋出一個異常,在構造函數中:

public MyClass() 
{ 
    if (typeof(T) == typeof(U)) 
    { 
     throw new Exception("T and U cannot be of the same type"); 
    } 
} 

什麼你應該做的是使用不同的名稱,以便兩個方法名不會相互衝突。這是在這種情況下工作的最安全的方式:

public DoSomethingWithFirst() 
{ 
    // For T 
} 

public DoSomethingWithSecond() 
{ 
    // For U 
} 
1

那麼,如果您不想撥打DoSomething,那麼能夠讓T和U成爲相同類型嗎?如果是這樣,編譯器無故無法阻止真氣嗎?

實際上,如果您仔細選擇了該方法,則可以使用反射來調用的方法

我想說,如果編譯器應該做任何事情,它應該警告這個類的作者本身(而不是類的用戶),在某些情況下,重載可能導致模糊。坦率地說超載會導致很多問題 - 任何人輕推離它在危險的情況下將是一個很好的事情:)

1

你願意編譯器沒有允許這樣做? theres無限的情況下,這是沒有的。

0

順便說一句,如果你不控制類,你要允許被叫做MyClass<int, int>這些方法,你可以不用反思和它將在運行時成功,不會例外。例如,如果您創建一個需要TU作爲參數的通用方法,然後重載分辨率方法中可以告訴他們分開:

public static class MyClassExtensions 
{ 
    public static void DoSomethingT<T, U>(this MyClass<T, U> obj, T t) 
    { 
     obj.DoSomething(t); 
    } 

    public static void DoSomethingU<T, U>(this MyClass<T, U> obj, U u) 
    { 
     obj.DoSomething(u); 
    } 
} 

DoSomethingT會選擇DoSomething,需要一個T過載。這是在編譯時選擇的,並且對於所有TU的值都有效。然後,您可以撥打電話myObj.DoSomethingT(3),電話號碼爲MyClass<int, int>,它將毫無歧義地呼叫MyClass.DoSomething(T t)

(正如其他人所說,如果你確實控制了這個類,那麼你應該給這些方法不同的名字。)

相關問題