В Resharper 5 следующий код привел к предупреждению "Параметр может быть объявлен с базовым типом" для list
:
public void DoSomething(List<string> list)
{
if (list.Any())
{
// ...
}
foreach (var item in list)
{
// ...
}
}
В Resharper 6 это не так. Однако, если я изменю метод на следующий, я все равно получаю это предупреждение:
public void DoSomething(List<string> list)
{
foreach (var item in list)
{
// ...
}
}
Причина в том, что в этой версии список перечисляется только один раз, поэтому его изменение на IEnumerable<string>
не будет автоматически вводить другое предупреждение.
Теперь, если я изменил первую версию вручную, чтобы использовать IEnumerable<string>
вместо List<string>
, я получу это предупреждение ( "Возможное множественное перечисление IEnumerable" ) в обоих случаях list
в теле метода:
public void DoSomething(IEnumerable<string> list)
{
if (list.Any()) // <- here
{
// ...
}
foreach (var item in list) // <- and here
{
// ...
}
}
Я понимаю, почему, но мне интересно, как решить это предупреждение, предполагая, что для метода действительно нужен только IEnumerable<T>
, а не List<T>
, потому что я просто хочу перечислить элементы, и я не хотите изменить список.
Добавление list = list.ToList();
в начале метода заставляет предупреждение уходить:
public void DoSomething(IEnumerable<string> list)
{
list = list.ToList();
if (list.Any())
{
// ...
}
foreach (var item in list)
{
// ...
}
}
Я понимаю, почему это заставляет предупреждение уходить, но это выглядит как взломать меня...
Любые предложения, как лучше решить это предупреждение и использовать наиболее общий тип в сигнатуре метода?
Для хорошего решения должны быть решены следующие проблемы:
- В методе нет вызова
ToList()
, поскольку он имеет влияние на производительность. - Нет использования
ICollection<T>
или даже более специализированных интерфейсов/классов, поскольку они изменяют семантику метода, как видно из вызывающего. - Нет многократных итераций над
IEnumerable<T>
и, следовательно, риск доступа к базе данных несколько раз или аналогичных.
Примечание. Я знаю, что это не проблема Resharper, и поэтому я не хочу подавлять это предупреждение, но исправляю основную причину, поскольку это предупреждение является законным.
UPDATE:
Пожалуйста, не волнуйте Any
и foreach
. Мне не нужна помощь в объединении этих операторов, чтобы иметь только один перечисление перечислимого.
В этом методе действительно может быть что угодно, перечисляющее перечислимое множество раз!