我有一個通用的方法與無約束泛型類型。如果類型T實現接口,我需要獲取不同的IEqualityComparer。在C#中如何獲得不同的IEqualityComparer <T>實例如果泛型類型實現接口
一個代碼看起來大致是這樣的:
public SomeState MergeCollection<T>(
ICollection<T> thisValue,
ICollection<T> otherValue,
SomeStrategy strategy = SomeStrategy.Default,
IEqualityComparer<T> comparer = null)
{
comparer = comparer ?? GetComparer<T>(strategy);
// code using comparer
}
public IEqualityComparer<T> GetComparer<T>(SomeStrategy strategy)
{
if(typeof(IMerge).IsAssignableFrom(typeof(T)))
{
return GetMergeComparer<T>(strategy);
}
else
{
return EqualityComparer<T>.Default;
}
}
似乎是模板專業化的典型案例尚未C#不支持這樣的功能,據我所知。我也在考慮實現一個策略模式的靜態類來交換抓取比較器的函數,但是靜態會爲所有類型實現,因此需要使用類型方法字典查找。爲此生成IL代碼似乎是最後的手段,考慮到代碼沒有被大量使用,不值得付出努力。
什麼是最好的方法來改變有問題的方法的行爲,所以如果T實現IMerge它會得到一個特殊情況?我問,因爲理論上應該可以在編譯時或至少在初始化時(靜態構造函數)定義行爲,如果它在運行時不會改變的話。
你現有的代碼有什麼問題?雖然你可以在靜態的'ConditionalWeakDictionary'中緩存'typeof(IMerge).IsAssignableFrom(typeof(T)))',這不太可能是值得打擾的,並且可能不會提高性能。 – CodesInChaos
我在最後添加了描述。它使用反射來改變編譯時已知的行爲,因此原則上它不被認爲是一個好的代碼。 – too
每種類型一次似乎是一個很好的折衷。問題是類本身不是通用的,只是方法是。我想這將需要創建一個單獨的通用靜態比較器工廠類與抓住比較器的屬性。似乎艱難:) – too