3

我目前有这个:

public void Load(IEnumerable<Guid> ids){
    f1(ids);
    f2(ids);
} 

为了避免 Resharper 曲线,建议的修复类似于

public void Load(IEnumerable<Guid> ids){
    var enumerable = ids as IList<Guid> ?? ids.ToList();
    f1(enumerable);
    f2(enumerable);
} 

问题是我永远想不出一个好名字来给“enumerable”起个名字,我不想叫它idsList,或者enumeratedIds,而enumerable肯定不行,而且ids已经被用于参数了。所以我的实际问题是这会解决这两个问题吗?

public void Load(IEnumerable<Guid> ids){
    ids = ids as IList<Guid> ?? ids.ToList();
    f1(ids);
    f2(ids);
}

是否存在上述情况会产生意外/低效的结果?

4

2 回答 2

4

是否存在上述情况会产生意外/低效的结果?

如果既不f1也不f2枚举 s 的整个列表Guid,并且ids未将 s 作为 a 提供给您List<Guid>,则转换为 list 会更昂贵。例如,当f1获取前五个元素,获取f2来自非缓存上下文并包含数千个项目时,该方法的效率将降低。FirstOrDefaultidsToList

为了避免 Resharper 曲线,建议的修复是......

并非所有 Resharper 警告都必须修复。该工具将您的注意力吸引到问题上,您可以自行修复它或忽略警告。Resharper 始终如一地寻找潜在的麻烦,但只有你知道里面发生了f1什么f2。如果您认为避免具体化列表更有效,请使用// ReSharper disable注释来避免使用曲线。

于 2013-09-23T21:33:59.383 回答
2

如果您正在使用实体框架,其中您有执行延迟的实体集合,那么这可能是一件非常糟糕的事情!想象一下,如果你的idsIEnumerable 真的是这样定义的:

var ids = MyDbContext.BillionsOfAccounts.Select(x => x.id);

并且您的函数是这样的(这可能无法编译,但可以理解):

public IEnumerable<T> f1(IEnumerable<T> query)
{
  if (query is IQueryable<T>)
  {
    return query.Take(10).ToList();
  }
  return null;
}

public IEnumerable<T> f2(IEnumerable<T> query)
{
  if (query is IQueryable<T>)
  {
    return query.Where(id => (id % 100000000) == 0).ToList();
  }
  return null;
}

如果是这种情况,那么您正在做的事情可能会尝试从数据库中获取数十亿条记录,而不是预期的 10 条记录。

也就是说,在很多情况下,您正在尝试的就是您想要的。正如其他人所说,您必须根据具体情况处理此问题。但是要回答您的问题,是的,在某些情况下这可能非常糟糕!

于 2013-09-23T21:42:56.007 回答