zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Linq 中带有迭代索引的 Select 扩展方法 **惊喜发现**,要多研究源码哦

扩展方法索引源码迭代 研究 发现 SELECT
2023-09-14 09:10:47 时间

给多行文字加上数字列表项

  • 常见写法,如下:但这里还是累赘了,因使用到了拉链函数 Zip 和生成范围的 Range,全纠缠到一块
using System.Linq;

static void ListIndex()
{
    var list = new List<string>()
    {
        "csharp","csdn","Microsoft","GitHub"
    };
	// 关键代码
    var items1 = list.Zip(Enumerable.Range(1, list.Count + 1), (item, i) => $"{i}. {item}").ToList();
    items1.ForEach(Console.WriteLine);
}

Select的一个带迭代变量的重载方法,可以简单快速实现

  • 实现同意功能,下面的代码,简洁明了许多
using System.Linq;

static void ListIndex()
{
    var list = new List<string>()
    {
        "csharp","csdn","Microsoft","GitHub"
    };
	// 关键代码
	var items = list.Select((item, i) => $"{i + 1}. {item}").ToList();{item}").ToList();
    items1.ForEach(Console.WriteLine);
}

Select扩展方法的底层实现源码
SelectIterator 枚举类可以看到,其实在底层也是单独给你定义了一个index,然后逐一回调给你的回调函数。实现方法多是高阶函数,需要一定的技术功底

public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    if (selector == null)
    {
        throw Error.ArgumentNull("selector");
    }
    return SelectIterator(source, selector);
}

private static IEnumerable<TResult> SelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
{
    int index = -1;
    foreach (TSource item in source)
    {
        index = checked(index + 1);
        yield return selector(item, index);
    }
}