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

一、标准查询运算符

1、概念

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

标准运算符的要点:

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

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

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

  • 被查询的集合对象叫作序列,它必须实现 IEnumerable接口,其中 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 返回
ToArray 将序列作为数组返回
ToList 将序列作为List 返回
ToDictionary 将序列作为 Dictionary返回
ToLookup 将序列作为 LookUp返回
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泛型类的扩展方法。

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

  • 1)由于运算符是泛型方法,因此每个方法名都具有相关的泛型参数(T)。
  • 2)由于运算符是扩展 IEnumerable 类的扩展方法,它们必须满足下面的语法条件。
    声明为 public 和 static。
    在第一个参数前有 this 扩展指示器。
    把 IEnumerable作为第一个参数类型。
public static int Count(this IEnumerable source);
public static T First(THIS IEnumerable source);
public static IEnumerable where(this IEnumerable 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(this IEnumerable source);
//添加泛型委托参数,接受单个T类型的输入参数并返回布尔值的委托对象
//委托代码的返回值必须指定元素是否应包含在总数中。
public static int Count(this IEnumerable source,
						   Func predicate);

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

Action 委托:

public delegate void Action ();
public delegate void Action (T1 a1);
public delegate void Action (T1 a1, T2 a2);
public delegate void Action (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 myDel = new Func(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 myDel = delegate (int x)
             {
                 return x % 2 == 1;
             };

            var countOdd = intArray.Count(myDel);

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

你可能感兴趣的:(CSharp,linq,c#)