Предположим, что у меня есть неограниченный общий метод, который работает на всех типах, поддерживающих равенство. Он выполняет парные проверки равенства и поэтому работает в O (n 2):
public static int CountDuplicates<T>(IList<T> list)
{
/* ... */
}
У меня также есть ограниченный общий метод, который работает только с типами, поддерживающими сортировку. Он начинается с сортировки списка в O (n log n) и затем подсчитывает все дубликаты за один проход:
public static int CountDuplicatesFast<T>(IList<T> list)
where T : IComparable<T>
{
/* ... */
}
Таким образом, вызывающий может выбрать вызов быстрого метода, если статически известно, что тип элементов списка поддерживает упорядочение. Может случиться так, что сам вызывающий объект работает с общим IList<T>
, где T не имеет ограничений, поэтому его единственный вариант для вызова первого (медленного) метода.
Теперь я хочу, чтобы первый метод проверялся во время выполнения, если тип T
фактически реализует интерфейс IComparable<T>
, и если это так, вызовите быстрый метод:
public static int CountDuplicates<T>(IList<T> list)
{
if (typeof(IComparable<T>).IsAssignableFrom(typeof(T)))
{
return CountDuplicatesFast(list);
}
else
{
/* use the slow algorithm */
}
}
Проблема заключается в том, что компилятор отклоняет вызов CountDuplicatesFast(list)
:
ошибка CS0314: Тип 'T' не может использоваться как параметр типа 'T' в общем типе или методе 'Program.CountDuplicatesFast <T> (System.Collections.Generic.IList <T> )'. Нет никакого преобразования бокса или преобразования параметра типа из 'T' в 'System.IComparable <T> '.
Можно ли убедить компилятор доверять мне, что я знаю, что делаю, и пропустить проверку ограничений?