(十一)CSharp-LINQ-标准查询运算符(3)

一、标准查询运算符

1、概念

标准查询运算符由一系列 API 方法组成,API 能让我们查询任何 .NET 数组或集合。

标准运算符的要点:

  • 标准查询运算符使用方法语法。

  • 一些运算符返回 Ienumerable 对象(或其他序列),而其他运算符返回标量。返回标量的运算符立即执行查询,并返回一个值,而不是一个可枚举类型对象。ToArray()、ToList() 等 ToCollection 运算符也会立即执行。

  • 很多操作都以一个谓词作为参数。谓词是一个方法,它以对象为参数,根据对象是否满足某个条件而返回 true 或 false.

  • 被查询的集合对象叫作序列,它必须实现 IEnumerable<T>接口,其中 T 是类型。

  • 用作方法的运算符直接作用于序列对象,在这里就是 numbers 数组。

  • 返回类型不是 Ienumerable 对象,而是 int。

   class Program
    {
        static int[] numbers = new int[] { 2, 4, 6 };
        static void Main(string[] args)
        {
            int total = numbers.Sum();
            int howMany = numbers.Count();

            Console.WriteLine($"Total:{ total },Count:{ howMany }");
            Console.ReadKey();
        }
    }

//标量对象:int
//序列:numbers
//运算符:Count()

表-20-1标准查询运算符

运算符名描述
Where根据给定的谓词对序列进行过滤
Select指定要包含一个对象或对象的一部分
SelectMany一种查询类型,返回集合的集合。该方法将这些结果合并为一个单独的集合
Take接受一个输入参数 count,返回序列中的前 count 个对象
Skip接受一个输入参数 count,跳过序列中的前 count 个对象,返回剩余对象
TakeWhile接受一个谓词,开始迭代序列,只要谓词对当前项的计算结果为 true,就选择该项。在谓词返回第一个 false 的时候,该项和其余项都被丢弃
SkipWhile接受一个谓词,开始迭代序列,只要谓词对当前项的计算结果为 true,就跳过该项。在谓词返回第一个 false 的时候,该项和其余项都会被选择
Join对两个序列执行内联结
GroupJoin可以产生层次结果的联结,第一个序列中的各个元素都与第二个序列中的元素集合相关联
Concat连接两个序列
OrderBy/ThenBy根据一个或多个键对序列中的元素按升序排序
Reverse反转序列中的元素
GroupBy分组序列中的元素
Distinct去除序列中的重复项
Union返回两个序列的并集
Intersect返回两个序列的交集
Except操作两个序列。返回的是第一个序列中不重复的元素减去同样位于第二个序列中的元素
AsEnumerable将序列作为 IEumerable <TSource> 返回
ToArray将序列作为数组返回
ToList将序列作为List <T> 返回
ToDictionary将序列作为 Dictionary<TKey,TElement>返回
ToLookup将序列作为 LookUp<TKey,TElement>返回
OfType所返回的序列中的元素是指定的类型
Cast将序列中所有的元素强制转换为给定的类型
SequenceEqual返回一个布尔值,指定两个序列是否相等
First返回序列中第一个与谓词匹配的元素。如果没有元素与谓词匹配,就抛出 InvalidOperation-Exception
FirstOrDefault返回序列中第一个与谓词匹配的元素。如果没有给出谓词,方法返回序列的第一个元素。如果没有元素与谓词匹配,就使用该类型的默认值
Last返回序列中最后一个与谓词匹配的元素。如果没有元素与谓词匹配,就抛出 InvalidOperation-Exception
LastOrDefault返回序列中最后一个与谓词匹配的元素。如果没有元素与谓词匹配,就返回默认值
Single返回序列中与谓词匹配的单个元素。如果没有元素匹配,或多于一个元素匹配,就抛出异常
SingleOrDefault返回序列中与谓词匹配的单个元素。如果没有元素匹配,或多于一个元素匹配,就返回默认值
ElementAt给定一个参数 n,返回序列中第 n + 1 个元素
ElementAtOrDefault给定一个参数 n,返回序列中第 n + 1 个元素。如果索引超出范围,就返回默认值
DefaultIfEmpty提供一个在序列为空(empty)时的默认值
Range给定一个 start 整型和 count 整型,该方法返回的序列包含 count 个整型,其中第一个元素的值为 start,每个后续元素都比前一个大 1
Repeat给定一个 T 类型的 element 和一个 count 整数,该方法返回的序列具有 count 个 elemen 副本
Empty返回给定类型 T 的空序列
Any返回一个布尔值,指明序列中是否存在满足谓词的元素
All返回一个布尔值,指明序列中的全部元素是否都满足谓词
Contains返回一个布尔值,指明序列中是否包含给定的元素
Count返回序列中元素的个数(int)。它的重载可以接受一个谓词,并返回序列中满足谓词的元素个数
Sum返回序列中值的总和
Min返回序列中最小的值
Max返回序列中最大的值
Average返回序列中值的平均值
Aggregate连续对序列中的各个元素应用给定的函数

2、标准查询运算符的签名

System.Linq.Enumerable 类声明了标准查询运算符方法。它们是扩展了 IEnumerable<T>泛型类的扩展方法。

如 3个标准查询运算符的签名:Count、First 和 Where。

  • 1)由于运算符是泛型方法,因此每个方法名都具有相关的泛型参数(T)。
  • 2)由于运算符是扩展 IEnumerable 类的扩展方法,它们必须满足下面的语法条件。
    声明为 public 和 static。
    在第一个参数前有 this 扩展指示器。
    把 IEnumerable<T>作为第一个参数类型。
public static int Count<T>(this IEnumerable<T> source);
public static T First<t>(THIS IEnumerable<T> source);
public static IEnumerable<T> where<T>(this IEnumerable<T> source, ...);

//this:扩展治时期

示例:

     static void Main(string[] args)
        {
            int[] intArray = new int[] { 3, 4, 5, 6, 7, 9 };
            var count1 = Enumerable.Count(intArray);//方法语法
            var firstNum1 = Enumerable.First(intArray);//方法语法

            var count2 = intArray.Count();//扩展方法
            var firstNum2 = intArray.First();//扩展方法

            Console.WriteLine($"Count:{ count1 }, FirstNumber:{ firstNum1 }");
            Console.WriteLine($"Count:{ count2 }, FirstNumber:{ firstNum2 }");

            Console.ReadKey();
        }

输出结果:

Count:6, FirstNumber:3
Count:6, FirstNumber:3

3、查询表达式和标准查询运算符

两者可以组合使用,示例:

 static void Main(string[] args)
        {
            var numbers = new int[] { 2, 6, 4, 8, 10 };
            int howMany = (from n in numbers
                           where n < 7
                           select n).Count();

            Console.WriteLine($"Count:{ howMany }");

            Console.ReadKey();
        }

输出结果:

Count:3

4、将委托作为参数

要点:

  • 泛型委托用于给运算符提供用户自定义的代码。

签名:

//运算符形式
public static int Count<T>(this IEnumerable<T> source);
//添加泛型委托参数,接受单个T类型的输入参数并返回布尔值的委托对象
//委托代码的返回值必须指定元素是否应包含在总数中。
public static int Count<T>(this IEnumerable<T> source,
						   Func<T,bool> predicate);

//泛型委托: Func<T,bool> predicate

使用 Lambda 示例:

        static void Main(string[] args)
        {
            int[] intArray = new int[] { 3, 4, 5, 6, 7, 9 };
            var countOdd = intArray.Count(n => n % 2 == 1);

            Console.WriteLine($"Count of odd numbers:{ countOdd }");
            Console.ReadKey();
        }

输出结果:

Count of odd numbers:4

.NET 框架定义了两套泛型委托类型来用于标准查询运算符,即 Func 委托和 Action 委托。

Func 委托:

public delegate TR Func<out TR>();
public delegate TR Func<in T1, out TR>(T1 a1);
public delegate TR Func<in T1, in T2, out TR>(T1 a1, T2 a2);
public delegate TR Func<in T1, in T2, in T3, out TR>(T1 a1, T2 a2, T3 a3);
  • 返回类型参数中 out 关键字,使之协变。
  • 输入参数有一个 in 关进啊,使之可以逆变。

Action 委托:

public delegate void Action ();
public delegate void Action<in T1> (T1 a1);
public delegate void Action<in T1, in T2> (T1 a1, T2 a2);
public delegate void Action<in T1, in T2, in T3> (T1 a1, T2 a2, T3 a3);

使用委托参数的示例

    class Program
    {
        static bool IsOdd(int x) //委托对象使用的方法
        {
            return x % 2 == 1;
        }

        static void Main(string[] args)
        {
            int[] intArray = new int[] { 3, 4, 5, 6, 7, 9 };

            Func<int, bool> myDel = new Func<int, bool>(IsOdd);//委托对象
            var countOdd = intArray.Count(myDel);//使用委托
           
            Console.WriteLine($"Count of odd numbers:{ countOdd }");
            Console.ReadKey();
        }
    }

输出结果:

Count of odd numbers:4

5、使用 Lambda 表达式参数的示例

示例:

 static void Main(string[] args)
        {
            int[] intArray = new int[] { 3, 4, 5, 6, 7, 9 };

            var countOdd = intArray.Count( x => x % 2 == 1);
           
            Console.WriteLine($"Count of odd numbers:{ countOdd }");
            Console.ReadKey();
        }

//Lambda 表达式:x => x % 2 == 1

6、匿名方法替代 Lambda 表达式

 static void Main(string[] args)
        {
            int[] intArray = new int[] { 3, 4, 5, 6, 7, 9 };

            Func<int, bool> myDel = delegate (int x)
             {
                 return x % 2 == 1;
             };

            var countOdd = intArray.Count(myDel);

            Console.WriteLine($"Count of odd numbers:{ countOdd }");
            Console.ReadKey();
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值