C# 为什么Resharper建议更改代码,然后抱怨更改?
我有这个密码:C# 为什么Resharper建议更改代码,然后抱怨更改?,c#,linq,resharper,C#,Linq,Resharper,我有这个密码: return children.SelectMany(c => GetChildControls<TControl>(c)).Concat(children); returnchildren.SelectMany(c=>GetChildControls(c)).Concat(children); …Resharper建议我将其更改为: return children.SelectMany(GetChildControls<TControl>).C
return children.SelectMany(c => GetChildControls<TControl>(c)).Concat(children);
returnchildren.SelectMany(c=>GetChildControls(c)).Concat(children);
…Resharper建议我将其更改为:
return children.SelectMany(GetChildControls<TControl>).Concat(children);
返回子项。选择many(GetChildControls)。Concat(childs);
在这方面:
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);
}
内部静态IEnumerable GetChildControls(此控件),其中TControl:Control
{
var children=control.Controls!=null?control.Controls.OfType():Enumerable.Empty();
返回children.SelectMany(GetChildControls).Concat(children);
}
正如您可能看到的,不同之处在于,行的“改进”版本中插入了“(c)”
但现在它将其标记为可疑,并表示“可能多次枚举IEnumerable”
是的,没错,可以/应该有多个,但为什么它会抱怨呢?我是否应该将其恢复到以前的状态?ReSharper为您发现的问题是您正在枚举
子对象两次。具体来说,第一次调用children时枚举children
。选择many(GetChildControls)
,另一次调用.Concat(children)
。ReSharper警告您这一点,因为每个枚举可能导致不同的结果,或者每个枚举可能代价高昂。有关更多详细信息,请参阅
一个解决办法是
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);
}
内部静态IEnumerable GetChildControls(此控件),其中TControl:Control
{
var children=control.Controls.OfType().ToList();
返回children.SelectMany(GetChildControls).Concat(children);
}
这确保了创建方法后,子对象
不会在方法内部发生变化(当然,除非您自己对其进行了变异),并且只会枚举一次。ReSharper为您发现的问题是,您正在枚举子对象
。具体来说,第一次调用children时枚举children
。选择many(GetChildControls)
,另一次调用.Concat(children)
。ReSharper警告您这一点,因为每个枚举可能导致不同的结果,或者每个枚举可能代价高昂。有关更多详细信息,请参阅
一个解决办法是
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);
}
内部静态IEnumerable GetChildControls(此控件),其中TControl:Control
{
var children=control.Controls.OfType().ToList();
返回children.SelectMany(GetChildControls).Concat(children);
}
这确保了创建方法后,子对象在方法内部不会发生变化(当然,除非您自己对其进行了变异),并且只会枚举一次。我的猜测是,Resharper对每行一次建议的代码更改数量有限制。“可能的多重枚举”问题在两个版本的代码中都存在,但Resharper仅在“改进”完成且该消息消失时才显示它。我猜Resharper对每行一次建议的代码更改数量有限制。“可能的多重枚举”问题在两个版本的代码中都存在,但Resharper仅在“改进”完成且该消息消失时才显示该问题。在您的代码中,我得到“方法”System.Linq.Enumerable.SelectMany(System.Collections.Generic.IEnumerable,System.Func)的类型参数'无法从用法中推断。请尝试显式指定类型参数。“抱歉!我没有注意到您的扩展方法是此控件
,而不是此t控件
。更新后的答案应该适用于我得到的代码,“无法从用法推断出方法'System.Linq.Enumerable.SelectMany(System.Collections.Generic.IEnumerable,System.Func)'的类型参数。请尝试显式指定类型参数。”对此表示抱歉!我没有注意到您的扩展方法是此控件
,而不是此t控件
。更新后的答案应该有效