在 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>
,则在方法体中 list
的两个出现都会收到警告("可能多次枚举 IEnumerable")。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)
{
// ...
}
}
我明白这样做可以消除警告,但对我来说看起来有点像一个hack... 有什么建议可以更好地解决警告,并在方法签名中仍然使用最通用的类型吗?要解决以下所有问题才能得到一个好的解决方案:
- 不在方法内调用
ToList()
,因为它会影响性能 - 不使用
ICollection<T>
或更专业化的接口/类,因为它们会改变从调用者看到的方法语义。 - 不要多次迭代
IEnumerable<T>
,以避免多次访问数据库或类似的情况。
更新: 请不要关心
Any
和 foreach
。 我不需要帮助将这些语句合并为只枚举可枚举对象的一个语句。 实际上,在此方法中,任何多次枚举可枚举对象的行为都可能导致问题!