Пожалуйста, проверьте следующие коды сегментов:Общий метод обрабатывает IEnumerable иначе, чем общий тип
public interface ICountable { }
public class Counter<T>
where T : ICountable
{
public int Count(IEnumerable<T> items)
{
return 0;
}
public int Count(T Item)
{
return 0;
}
}
public class Counter
{
public int Count<T>(IEnumerable<T> items)
where T : ICountable
{
return 0;
}
public int Count<T>(T Item)
where T : ICountable
{
return 0;
}
}
Две версии счетчика отличаются только в описании общего параметра. Один из них определяет как типичный параметр типа, другой - как общий аргумент. Оба ограничивают аргументы метода для реализации интерфейса ICountable. Я буду называть их конкретных и неспецифических соответственно.
Теперь я определяю класс, который реализует интерфейсICountable и коллекцию экземпляров:
public class CItem : ICountable { }
var countables = new List<CItem>();
Тогда, я хотел бы использовать оба класса Счетчик на коллекции.
var specific = new Counter<CItem>();
var nonspecific = new Counter();
specific.Count(countables);
nonspecific.Count(countables);
Специальный счетчик признает, что countables коллекция должна попадать в подписи Int Count (IEnumerable), но неспецифическая версия не делает. Я получаю сообщение об ошибке:
The type '
System.Collections.Generic.List<CItem>
' cannot be used as type parameter 'T
' in the generic type or method 'Counter.Count<T>(T)
'. There is no implicit reference conversion fromList<CItem>
' toICountable
.
Похоже, что нестандартная версия использует неправильную подпись для коллекции.
Почему они ведут себя по-другому? Как указать конкретную версию, чтобы вести себя так же, как и другая?
Примечание: Я знаю, что этот пример нереалистичен. Однако я столкнулся с этой проблемой в довольно сложном сценарии с методами расширения. Я использую эти классы для простоты
Заранее спасибо
, если указать общий тип явно на как 'nonspecific.Count (countables)', которые будут работать слишком –
, если вы определяете '' countables' с IEnumerable countables = новый список () 'выбрана правильная перегрузка , –
SWeko
Перегрузки метода Count() неоднозначны, оба могут принимать список в качестве аргумента. Однако один из них нарушает ограничение в * конкретном * случае передачи списка. Это не очень хорошо, если вы используете другой тип, который реализует IEnumerable * и * ICountable, то это действительно двусмысленно. C# не позволяет объявлять общий тип/метод, который может случайно не скомпилироваться. –