Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么Resharper建议更改代码,然后抱怨更改?_C#_Linq_Resharper - Fatal编程技术网

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控件
。更新后的答案应该有效