c# - 使用函数结果作为源的 LINQ 延迟执行(例如 Console.ReadLine)

标签 c# linq deferred-execution

函数的结果是LINQ 查询的源。我希望每次使用查询时都能延迟评估它,而不是在创建查询时被锁定。这是我的意思的一个例子:

var query = from c in Console.ReadLine()
            group c by char.IsDigit(c) into gr
            select new { IsDigit = gr.Key, Count = gr.Count() };

Console.WriteLine() 仅在创建 query 时运行一次,即使没有调用像 ToList() 这样的终止方法。我想要的是仅当我使用 ToList() 查询时才执行 Console.WriteLine() (或任何其他函数) >Count() 等等

最佳答案

如果您不介意一些额外的基础设施,这还不错 - 您可以创建一个 DeferredEnumerable<T>每次请求迭代器时只执行给定委托(delegate)的类。静态非泛型类可以帮助进行类型推断。完整示例:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

// Just for type inference...
public static class DeferredEnumerable
{
    public static IEnumerable<T> For<T>(Func<IEnumerable<T>> func) =>
        new DeferredEnumerable<T>(func);
}

public sealed class DeferredEnumerable<T> : IEnumerable<T>
{
    private readonly Func<IEnumerable<T>> func;

    public DeferredEnumerable(Func<IEnumerable<T>> func)
    {
        this.func = func;
    }

    public IEnumerator<T> GetEnumerator() => func().GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

class Test
{
    static void Main()
    {
        var query = 
            from c in DeferredEnumerable.For(Console.ReadLine)
            group c by char.IsDigit(c) into gr
            select new { IsDigit = gr.Key, Count = gr.Count() };


        Console.WriteLine("First go round");
        Console.WriteLine(string.Join(Environment.NewLine, query));

        Console.WriteLine("Second go round");
        Console.WriteLine(string.Join(Environment.NewLine, query));
    }
}

关于c# - 使用函数结果作为源的 LINQ 延迟执行(例如 Console.ReadLine),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45612948/

相关文章:

c# - 是否可以通过 HwndHost 控件绘制 WPF 控件?

c# - 启用/禁用多个游戏对象的网格渲染器

python - appengine 延迟任务问题,执行抛出未知错误

objective-c - 在 Objective-C 中实现 Go 中的 ‘defer’ 语句?

c# - 如何格式化 MS Chart 控件中的 Axis

c# - 在 C# 的同一类中的另一个委托(delegate)函数中使用两个委托(delegate)函数的返回 View

c# - LINQ 相对于函数式方法链的优势

c# - 我如何使用 linq 和 c# 将字典字符串字符串转换为字符串和字符串的键值对数组

c# - LINQ Distinct with EqualityComparer<T>.Default : IEquatable<T> implementation ignored?

c# - 是否可以确定 IEnumerable<T> 是否已延迟执行挂起?