«Возможное множественное перечисление IEnumerable» против «Параметр может быть объявлен с базовым типом»

В 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)
    {
        // ...
    }
}

Я понимаю, почему это заставляет предупреждение исчезнуть, но это немного похоже на взлом мне ...
Есть ли предложения, как лучше устранить это предупреждение и по-прежнему использовать наиболее общий тип в сигнатуре метода?
Для получения хорошего решения необходимо решить следующие проблемы:

  1. Нет вызова ToList () внутри метода, потому что это влияет на производительность
  2. Не используется ICollection или даже более специализированных интерфейсов / классов, потому что они изменяют семантику метода, как видно из вызывающего.
  3. Отсутствие многократных итераций над IEnumerable и, таким образом, рискованный доступ к базе данных раз или подобное.

Примечание: я знаю, что это не проблема Resharper, и поэтому я не хочу подавлять это предупреждение, но хочу исправить основную причину, поскольку предупреждение является допустимым.

ОБНОВЛЕНИЕ: Пожалуйста, не обращайте внимания на Any и foreach . Мне не нужна помощь в объединении этих операторов, чтобы получить только одно перечисление перечислимого.
В этом методе действительно может быть что угодно, многократно перечисляющее перечислимое!

15
задан rae1 7 June 2013 в 16:15
поделиться