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