擴大的例子突出問題:
public class BidirectionalMap<T1,T2>
{
public void Remove(T1 item) {}
public void Remove(T2 item) {}
public static void Test()
{
//This line compiles
var possiblyBad = new BidirectionalMap<string, string>();
//This causes the compiler to fail with an ambiguous invocation
possiblyBad.Remove("Something");
}
}
因此,答案是,即使你不能指定約束T1 = T2,也不要緊,因爲編譯器只要你試圖做一些違反隱含約束的事情就會失敗。它仍然在編譯時捕獲失敗,所以你可以使用這些重載而不受懲罰。這有點奇怪,因爲你可以創建一個地圖實例(甚至可以編寫IL代碼來適當地操作地圖),但C#編譯器不會讓你通過任意解決模糊的重載而造成破壞。
一方面要注意的是,如果你不小心,這種重載可能會導致一些奇怪的行爲。如果你有一個BidirectionalMap<Animal, Cat>
和貓:動物,可以考慮將與此代碼發生的事情:
Animal animal = new Cat();
map.Remove(animal);
這將調用了一個動物的過載,所以它會嘗試刪除鍵,即使你可能已經打算刪除值Cat。這是一個有些人爲的情況,但是當由於方法重載而出現非常不同的行爲時,請謹慎行事。在這種情況下,如果您只是給方法不同的名稱,反映它們的不同行爲(比如RemoveKey和RemoveValue,假設),則讀取和維護可能會更容易。
您可以在構造函數中始終拋出一個'ShouldBeBeCompileTimeError()' 。 :-) – foson
可能是因爲它沒有意義,它們是泛型,不應該被類型「約束」。 – GriffinHeart
出於好奇,如果不滿足這個約束,會有什麼負面影響?來自同一組的對象之間的映射是非常普遍的要求。 –