c# - 以 ReSharper 方式使用嵌套条件循环有什么好处?

标签 c# wpf loops foreach resharper

当使用内部有嵌套条件的 foreach 循环时,我曾经这样写:

foreach (RadioButton item in listOfRadioButtons)
{
    if (item.IsChecked == true)
    {
         // sometging
    }
}

但我已经安装了 ReSharper,它建议将此循环更改为以下形式(删除 if 并使用 lambda):

foreach (RadioButton item in listOfRadioButtons.Where(item => item.IsChecked == true))
{
    // something
}

根据我的经验,ReSharper 方式将循环两次:一次生成过滤后的 IEnumerable,然后再次循环 .Where 查询的结果。

我是对的?如果是这样,为什么 ReSharper 建议这样做?因为在我看来,第一种也更靠谱。

注意:WPF RadioButton 的默认 IsChecked 属性是一个 Nullable bool,因此它需要一个 == true、一个 .Value 或一个转换为 bool 的条件以返回 bool。

最佳答案

In my experience, the ReSharper way will loop two times: one to generate the filtered IEnumerable, and after to loop the results of the .Where query again.

不会,它只会循环一次。 Where 不会循环您的集合 - 它只会创建用于枚举您的集合的迭代器。下面是 LINQ 解决方案的样子:

using(var iterator = listOfRadioButtons.Where(rb => rb.IsChecked == true))
{
    while(iterator.MoveNext())
    {
        RadioButton item = iterator.Current;
        // something
    }
}

您的原始代码在性能方面更好 - 您将避免创建委托(delegate)并将其传递给 WhereEnumerableIterator 的实例,然后为源序列中的每个项目执行委托(delegate)。但是您应该注意,正如@dcastro 指出的那样,差异将非常小并且在您必须优化此特定循环之前不值得一提。

ReSharper 建议的解决方案(可能)更利于可读性。我个人喜欢循环中的简单 if 条件。

更新:Where迭代器可以简化为(也省略了一些接口(interface))

public class WhereEnumerableIterator<T> : IEnumerable<T>, IDisposable
{
    private IEnumerator<T> _enumerator;
    private Func<T,bool> _predicate;

    public WhereEnumerableIterator(IEnumerable<T> source, Func<T,bool> predicate)
    {
        _predicate = predicate;
        _enumerator = source.GetEnumerator();
    }

    public bool MoveNext()
    {
        while (_enumerator.MoveNext())
        {
            if (_predicate(_enumerator.Current))
            {
                Current = _enumerator.Current;
                return true;
            }
        }

        return false;
    }

    public T Current { get; private set; }

    public void Dispose()
    {
        if (_enumerator != null)
            _enumerator.Dispose();
    }
}

此处的主要思想 - 只有当您要求它移至下一项时,它才会枚举原始来源。然后迭代器转到原始源中的下一个项目并检查它是否与谓词匹配。如果找到匹配项,则它返回当前项目并暂停枚举源。

因此,除非您不向此迭代器询问项目,否则它不会枚举源。如果您将在此迭代器上调用 ToList(),它将枚举源序列并返回所有匹配项,这些项将保存到新列表中。

关于c# - 以 ReSharper 方式使用嵌套条件循环有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21406528/

相关文章:

c# - 如何从 FFT 获取低音、中音、高音数据

c# - 使用 C# API 在 Facebook 中创建事件时出现 TargetParameterCountException

c# - 如何在 C# 中格式化显示在 MessageBox 中的字符串?

java - 使用嵌套 for 循环初始化 2D 数组并查找模式

C#:访问 ".NET CLR Memory category"的 PerformanceCounters

c# - 测试 WCF Web 服务

wpf - 我还能如何在 View 模型的 View 中触发动画?

c# - WPF Datagrid 数据绑定(bind)到具有静态属性的类和包含动态属性值条目的字典

PHP - 执行长脚本时可能遇到的障碍

python - 检查两个给定列表中的一个是否是另一个的循环排列