为什么Resharper建议改变代码,然后抱怨改变?

时间:2016-04-12 22:51:19

标签: c# linq resharper

我有这段代码:

return children.SelectMany(c => GetChildControls<TControl>(c)).Concat(children);

......并且Resharper建议我将其更改为:

return children.SelectMany(GetChildControls<TControl>).Concat(children);

在上下文中:

internal static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control
{
    var children = control.Controls != null ? control.Controls.OfType<TControl>() : Enumerable.Empty<TControl>();
    return children.SelectMany(GetChildControls<TControl>).Concat(children);
}

正如您所看到的那样,差异在于该行的“改进”版本已经省略了插入的“(c)”

但现在它标志着可疑,说,“可能多次枚举IEnumerable”

是的,那是对的,可能/应该有多个,但为什么会这样做呢?我应该将它恢复到以前的状态吗?

1 个答案:

答案 0 :(得分:2)

ReSharper为您提供的问题是,您要两次枚举children。具体来说,您第一次在children拨打电话时枚举children.SelectMany(GetChildControls<TControl>),而在您拨打.Concat(children)时再次点名internal static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control { var children = control.Controls.OfType<TControl>().ToList(); return children.SelectMany(GetChildControls<TControl>).Concat(children); } 。 ReSharper会对此发出警告,因为每次枚举都可能导致不同的结果,或者每次枚举都可能代价高昂。有关详细信息,请参阅this question

一种解决方案是

children

确保Collection.find()在你创建它之后不会在你的方法中发生变化(当然,除非你自己改变它),并且它只会被枚举一次。