Имам общ метод с неограничен общ тип. Трябва да получа различен 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? Питам, защото теоретично трябва да е възможно да се дефинира поведение по време на компилиране или поне по време на инициализация (статичен конструктор), ако то няма да се промени по време на изпълнение.
typeof(IMerge).IsAssignableFrom(typeof(T)))
в статиченConditionalWeakDictionary
, това едва ли ще си струва труда и вероятно няма да подобри производителността толкова много. - person CodesInChaos   schedule 13.10.2015