.NET 6 中的 LINQ 改进

*或缺省方法的默认值

方法返回序列的第一个元素,如果未找到任何元素,则返回默认值。在 .NET 6 中,可以重写默认值。您也可以覆盖SingleOrDefault 和 LastOrDefault方法默认值。

List<int> list1 = new() { 1, 2, 3 };
int item1 = list1.FirstOrDefault(i => i == 4, -1);
Console.WriteLine(item1); // -1

List<string> list2 = new() { "Item1" };
string item2 = list2.SingleOrDefault(i => i == "Item2", "Not found");
Console.WriteLine(item2); // Not found

新 *按方法

.NET 6 引入了新的枚举。通过* 方法。提供了一个"键选择器"来比较元素。

新方法:

  • MinBy
  • MaxBy
  • DistinctBy
  • ExceptBy
  • Intersect
  • Union 
    List<Product> products = new()
    {
        new() { Name = "Product1", Price = 100 },
        new() { Name = "Product2", Price = 5 },
        new() { Name = "Product3", Price = 50 },
    };
    
    Product theCheapestProduct = products.MinBy(x => x.Price);
    Product theMostExpensiveProduct = products.MaxBy(x => x.Price);
    Console.WriteLine(theCheapestProduct);
    // Output: Product { Name = Product2, Price = 5 }
    Console.WriteLine(theMostExpensiveProduct);
    // Output: Product { Name = Product1, Price = 100 }
    
    record Product
    {
        public string Name { get; set; }
        public decimal Price { get; set; }
    }

    新的块方法

    如果需要将序列的元素拆分为块,则不必再在 .NET 6 中自行实现它。它引入了一个新的Enumerable.Chunk扩展方法。

    IEnumerable<int> numbers = Enumerable.Range(1, 505);
    IEnumerable<int[]> chunks = numbers.Chunk(100);
    
    foreach (int[] chunk in chunks)
    {
        Console.WriteLine($"{chunk.First()}...{chunk.Last()}");
    }
    
    //  Output:
    //  1...100
    //  101...200
    //  201...300
    //  301...400
    //  401...500
    //  501...505

    三向拉链法

    Enumerable.Zip扩展方法生成一个元组序列,其中包含来自两个指定序列的元素。在 .NET 6 中,它可以组合来自三个序列的元组。

    它不能组合来自四个或更多序列的元组。

    int[] numbers = { 1, 2, 3, 4, };
    string[] months = { "Jan", "Feb", "Mar" };
    string[] seasons = { "Winter", "Winter", "Spring" };
    
    var test = numbers.Zip(months).Zip(seasons);
    
    foreach ((int, string, string) zipped in numbers.Zip(months, seasons))
    {
        Console.WriteLine($"{zipped.Item1} {zipped.Item2} {zipped.Item3}");
    }
    // Output:
    // 1 Jan Winter
    // 2 Feb Winter
    // 3 Mar Spring

     

    ElementAt 方法中的索引支持

    .NET Core 3.0 引入了Index结构,C# 编译器使用它来支持新的一元前缀"hat"运算符 (^)。它表示"从集合的末尾"索引。在 .NET 6 中,Enumerable.ElementAt方法支持Index

    IEnumerable<int> numbers = new int[] { 1, 2, 3, 4, 5 };
    int last = numbers.ElementAt(^0);
    Console.WriteLine(last); // 5

    "取"方法中的范围支持

    Range结构已在 .NET Core 3.0 中引入。C# 编译器使用它来支持范围运算符 '..'

    在 .NET 6 中,Enumerable.Take方法支持Range

    IEnumerable<int> numbers = new int[] { 1, 2, 3, 4, 5 };
    
    IEnumerable<int> taken1 = numbers.Take(2..4);
    foreach (int i in taken1)
        Console.WriteLine(i);
    // Output:
    // 3
    // 4
    
    IEnumerable<int> taken2 = numbers.Take(..3);
    foreach (int i in taken2)
        Console.WriteLine(i);
    // Output:
    // 1
    // 2
    // 3
    
    IEnumerable<int> taken3 = numbers.Take(3..);
    foreach (int i in taken3)
        Console.WriteLine(i);
    // Output:
    // 4
    // 5

    使用 TryGetNonEnumeratedCount 避免枚举

    .NET 6 引入了一个新的Enumerable.TryGetNonEnumerated方法。它尝试在不强制枚举的情况下确定序列中的元素数。它对于IQueryable非常有用,在调用Enumerable.Count时,您不希望评估整个查询。

    IEnumerable<int> numbers = GetNumbers();
    TryGetNonEnumeratedCount(numbers);
    // Output: Could not get a count of numbers without enumerating the sequence 
    
    IEnumerable<int> enumeratedNumbers = numbers.ToList();
    
    var test = enumeratedNumbers.ElementAt(-1);
    
    TryGetNonEnumeratedCount(enumeratedNumbers);
    // Output: Count: 5
    
    void TryGetNonEnumeratedCount(IEnumerable<int> numbers)
    {
        if (numbers.TryGetNonEnumeratedCount(out int count))
            Console.WriteLine($"Count: {count}");
        else
            Console.WriteLine("Could not get a count of numbers without enumerating the sequence");
    }
    
    IEnumerable<int> GetNumbers()
    {
        yield return 1;
        yield return 2;
        yield return 3;
        yield return 4;
        yield return 5;
    }

     

posted @ 2021-12-31 13:52  Tammytan  阅读(126)  评论(0编辑  收藏  举报