一、标准查询运算符
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:扩展治时期
示例:文章来源地址https://www.toymoban.com/news/detail-504471.html
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文章来源:https://www.toymoban.com/news/detail-504471.html
.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();
}
到了这里,关于(十一)CSharp-LINQ-标准查询运算符(3)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!