Linq标准查询运算符

标准查询运算符 返回类型 立即执行 延迟的流式处理执行 延迟非流式处理执行
Aggregate TSource X
All Boolean X
Any Boolean X
AsEnumerable IEnumerable X
Average 单个数值 x
Cast IEnumerable X
Concat IEnumerable X
Contains Boolean X
Count Int32 X
DefaultIfEmpty IEnumerable X
Distinct IEnumerable X
ElementAt TSource X
ElementAtOrDefault TSource? X
Empty IEnumerable X
Except IEnumerable X X
First TSource X
FirstOrDefault TSource? X
GroupBy IEnumerable X
GroupJoin IEnumerable X X
Intersect IEnumerable X X
Join IEnumerable X X
Last TSource X
LastOrDefault TSource? X
LongCount Int64 X
Max 单个数值 TSource 或 TResult? X
Min 单个数值 TSource 或 TResult? X
OfType IEnumerable X
OrderBy IOrderedEnumerable X
OrderByDescending IOrderedEnumerable X
Range IEnumerable X
Repeat IEnumerable X
Reverse IEnumerable X
Select IEnumerable X
SelectMany IEnumerable X
SequenceEqual Boolean X
Single TSource X
SingleOrDefault TSource? X
Skip IEnumerable X
SkipWhile IEnumerable X
Sum 单个数值 x
Take IEnumerable X
TakeWhile IEnumerable X
ThenBy IOrderedEnumerable X
ThenByDescending IOrderedEnumerable X
ToArray TSource[] 数组 X
ToDictionary Dictionary<TKey,TValue> X
ToList IList X
ToLookup ILookup<TKey,TElement> X
Union IEnumerable X
Where IEnumerable X

注:整理自C# 中的 LINQ 查询简介

Aggregate

对序列应用累加器函数。 将指定的种子值用作累加器的初始值,并使用指定的函数选择结果值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };

// Determine whether any string in the array is longer than "banana".
string longestName =
fruits.Aggregate("banana",
(longest, next) =>
next.Length > longest.Length ? next : longest,
// Return the final result as an upper case string.
fruit => fruit.ToUpper());

Console.WriteLine(
"The fruit with the longest name is {0}.",
longestName);

// This code produces the following output:
//
// The fruit with the longest name is PASSIONFRUIT.
1
2
3
4
5
6
7
8
9
10
11
int[] ints = { 4, 8, 8, 3, 9, 0, 7, 8, 2 };

// Count the even numbers in the array, using a seed value of 0.
int numEven = ints.Aggregate(0, (total, next) =>
next % 2 == 0 ? total + 1 : total);

Console.WriteLine("The number of even integers is: {0}", numEven);

// This code produces the following output:
//
// The number of even integers is: 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string sentence = "the quick brown fox jumps over the lazy dog";

// Split the string into individual words.
string[] words = sentence.Split(' ');

// Prepend each word to the beginning of the
// new sentence to reverse the word order.
string reversed = words.Aggregate((workingSentence, next) =>
next + " " + workingSentence);

Console.WriteLine(reversed);

// This code produces the following output:
//
// dog lazy the over jumps fox brown quick the

All

确定序列中的所有元素是否都满足条件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}

public static void AllEx()
{
// Create an array of Pets.
Pet[] pets = { new Pet { Name="Barley", Age=10 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=6 } };

// Determine whether all pet names
// in the array start with 'B'.
bool allStartWithB = pets.All(pet =>
pet.Name.StartsWith("B"));

Console.WriteLine(
"{0} pet names start with 'B'.",
allStartWithB ? "All" : "Not all");
}

// This code produces the following output:
//
// Not all pet names start with 'B'.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
class Person
{
public string LastName { get; set; }
public Pet[] Pets { get; set; }
}

public static void AllEx2()
{
List<Person> people = new List<Person>
{ new Person { LastName = "Haas",
Pets = new Pet[] { new Pet { Name="Barley", Age=10 },
new Pet { Name="Boots", Age=14 },
new Pet { Name="Whiskers", Age=6 }}},
new Person { LastName = "Fakhouri",
Pets = new Pet[] { new Pet { Name = "Snowball", Age = 1}}},
new Person { LastName = "Antebi",
Pets = new Pet[] { new Pet { Name = "Belle", Age = 8} }},
new Person { LastName = "Philips",
Pets = new Pet[] { new Pet { Name = "Sweetie", Age = 2},
new Pet { Name = "Rover", Age = 13}} }
};

// Determine which people have pets that are all older than 5.
IEnumerable<string> names = from person in people
where person.Pets.All(pet => pet.Age > 5)
select person.LastName;

foreach (string name in names)
{
Console.WriteLine(name);
}

/* This code produces the following output:
*
* Haas
* Antebi
*/
}

Any

确定序列中是否包含元素或存在元素满足指定条件。

1
2
3
4
5
6
7
8
9
List<int> numbers = new List<int> { 1, 2 };
bool hasElements = numbers.Any();

Console.WriteLine("The list {0} empty.",
hasElements ? "is not" : "is");

// This code produces the following output:
//
// The list is not empty.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}
class Person
{
public string LastName { get; set; }
public Pet[] Pets { get; set; }
}

public static void AnyEx2()
{
List<Person> people = new List<Person>
{ new Person { LastName = "Haas",
Pets = new Pet[] { new Pet { Name="Barley", Age=10 },
new Pet { Name="Boots", Age=14 },
new Pet { Name="Whiskers", Age=6 }}},
new Person { LastName = "Fakhouri",
Pets = new Pet[] { new Pet { Name = "Snowball", Age = 1}}},
new Person { LastName = "Antebi",
Pets = new Pet[] { }},
new Person { LastName = "Philips",
Pets = new Pet[] { new Pet { Name = "Sweetie", Age = 2},
new Pet { Name = "Rover", Age = 13}} }
};

// Determine which people have a non-empty Pet array.
IEnumerable<string> names = from person in people
where person.Pets.Any()
select person.LastName;

foreach (string name in names)
{
Console.WriteLine(name);
}

/* This code produces the following output:

Haas
Fakhouri
Philips
*/
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
public bool Vaccinated { get; set; }
}

public static void AnyEx3()
{
// Create an array of Pets.
Pet[] pets =
{ new Pet { Name="Barley", Age=8, Vaccinated=true },
new Pet { Name="Boots", Age=4, Vaccinated=false },
new Pet { Name="Whiskers", Age=1, Vaccinated=false } };

// Determine whether any pets over age 1 are also unvaccinated.
bool unvaccinated =
pets.Any(p => p.Age > 1 && p.Vaccinated == false);

Console.WriteLine(
"There {0} unvaccinated animals over age one.",
unvaccinated ? "are" : "are not any");
}

// This code produces the following output:
//
// There are unvaccinated animals over age one.

AsEnumerable

返回类型化为 IEnumerable 的输入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Custom class.
class Clump<T> : List<T>
{
// Custom implementation of Where().
public IEnumerable<T> Where(Func<T, bool> predicate)
{
Console.WriteLine("In Clump's implementation of Where().");
return Enumerable.Where(this, predicate);
}
}

static void AsEnumerableEx1()
{
// Create a new Clump<T> object.
Clump<string> fruitClump =
new Clump<string> { "apple", "passionfruit", "banana",
"mango", "orange", "blueberry", "grape", "strawberry" };

// First call to Where():
// Call Clump's Where() method with a predicate.
IEnumerable<string> query1 =
fruitClump.Where(fruit => fruit.Contains("o"));

Console.WriteLine("query1 has been created.\n");

// Second call to Where():
// First call AsEnumerable() to hide Clump's Where() method and thereby
// force System.Linq.Enumerable's Where() method to be called.
IEnumerable<string> query2 =
fruitClump.AsEnumerable().Where(fruit => fruit.Contains("o"));

// Display the output.
Console.WriteLine("query2 has been created.");
}

// This code produces the following output:
//
// In Clump's implementation of Where().
// query1 has been created.
//
// query2 has been created.

Average

计算数值序列的平均值。

1
2
3
4
5
6
7
8
9
long?[] longs = { null, 10007L, 37L, 399846234235L };

double? average = longs.Average();

Console.WriteLine("The average is {0}.", average);

// This code produces the following output:
//
// The average is 133282081426.333.
1
2
3
4
5
6
7
8
9
List<int> grades = new List<int> { 78, 92, 100, 37, 81 };

double average = grades.Average();

Console.WriteLine("The average grade is {0}.", average);

// This code produces the following output:
//
// The average grade is 77.6.
1
2
3
4
5
6
7
8
9
string[] fruits = { "apple", "banana", "mango", "orange", "passionfruit", "grape" };

double average = fruits.Average(s => s.Length);

Console.WriteLine("The average string length is {0}.", average);

// This code produces the following output:
//
// The average string length is 6.5.
1
2
3
4
5
6
7
8
9
string[] numbers = { "10007", "37", "299846234235" };

double average = numbers.Average(num => long.Parse(num));

Console.WriteLine("The average is {0}.", average);

// This code produces the following output:
//
// The average is 99948748093.

Cast

将 IEnumerable 的元素强制转换为指定的类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
System.Collections.ArrayList fruits = new System.Collections.ArrayList();
fruits.Add("mango");
fruits.Add("apple");
fruits.Add("lemon");

IEnumerable<string> query =
fruits.Cast<string>().OrderBy(fruit => fruit).Select(fruit => fruit);

// The following code, without the cast, doesn't compile.
//IEnumerable<string> query1 =
// fruits.OrderBy(fruit => fruit).Select(fruit => fruit);

foreach (string fruit in query)
{
Console.WriteLine(fruit);
}

// This code produces the following output:
//
// apple
// lemon
// mango

Concat

连接两个序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}

static Pet[] GetCats()
{
Pet[] cats = { new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };
return cats;
}

static Pet[] GetDogs()
{
Pet[] dogs = { new Pet { Name="Bounder", Age=3 },
new Pet { Name="Snoopy", Age=14 },
new Pet { Name="Fido", Age=9 } };
return dogs;
}

public static void ConcatEx1()
{
Pet[] cats = GetCats();
Pet[] dogs = GetDogs();

IEnumerable<string> query =
cats.Select(cat => cat.Name).Concat(dogs.Select(dog => dog.Name));

foreach (string name in query)
{
Console.WriteLine(name);
}
}

// This code produces the following output:
//
// Barley
// Boots
// Whiskers
// Bounder
// Snoopy
// Fido
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Pet[] cats = GetCats();
Pet[] dogs = GetDogs();

IEnumerable<string> query =
new[] { cats.Select(cat => cat.Name), dogs.Select(dog => dog.Name) }
.SelectMany(name => name);

foreach (string name in query)
{
Console.WriteLine(name);
}

// This code produces the following output:
//
// Barley
// Boots
// Whiskers
// Bounder
// Snoopy
// Fido

Contains

确定序列是否包含指定的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
string[] fruits = { "apple", "banana", "mango", "orange", "passionfruit", "grape" };

string fruit = "mango";

bool hasMango = fruits.Contains(fruit);

Console.WriteLine(
"The array {0} contain '{1}'.",
hasMango ? "does" : "does not",
fruit);

// This code produces the following output:
//
// The array does contain 'mango'.

Count

返回序列中的元素数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
string[] fruits = { "apple", "banana", "mango", "orange", "passionfruit", "grape" };

try
{
int numberOfFruits = fruits.Count();
Console.WriteLine(
"There are {0} fruits in the collection.",
numberOfFruits);
}
catch (OverflowException)
{
Console.WriteLine("The count is too large to store as an Int32.");
Console.WriteLine("Try using the LongCount() method instead.");
}

// This code produces the following output:
//
// There are 6 fruits in the collection.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Pet
{
public string Name { get; set; }
public bool Vaccinated { get; set; }
}

public static void CountEx2()
{
Pet[] pets = { new Pet { Name="Barley", Vaccinated=true },
new Pet { Name="Boots", Vaccinated=false },
new Pet { Name="Whiskers", Vaccinated=false } };

try
{
int numberUnvaccinated = pets.Count(p => p.Vaccinated == false);
Console.WriteLine("There are {0} unvaccinated animals.", numberUnvaccinated);
}
catch (OverflowException)
{
Console.WriteLine("The count is too large to store as an Int32.");
Console.WriteLine("Try using the LongCount() method instead.");
}
}

// This code produces the following output:
//
// There are 2 unvaccinated animals.

DefaultIfEmpty

返回 IEnumerable的元素;如果序列为空,则返回默认值单一实例集合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}

public static void DefaultIfEmptyEx1()
{
List<Pet> pets =
new List<Pet>{ new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };

foreach (Pet pet in pets.DefaultIfEmpty())
{
Console.WriteLine(pet.Name);
}
}

/*
This code produces the following output:

Barley
Boots
Whiskers
*/
1
2
3
4
5
6
7
8
9
10
11
12
List<int> numbers = new List<int>();

foreach (int number in numbers.DefaultIfEmpty())
{
Console.WriteLine(number);
}

/*
This code produces the following output:

0
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}

public static void DefaultIfEmptyEx2()
{
Pet defaultPet = new Pet { Name = "Default Pet", Age = 0 };

List<Pet> pets1 =
new List<Pet>{ new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };

foreach (Pet pet in pets1.DefaultIfEmpty(defaultPet))
{
Console.WriteLine("Name: {0}", pet.Name);
}

List<Pet> pets2 = new List<Pet>();

foreach (Pet pet in pets2.DefaultIfEmpty(defaultPet))
{
Console.WriteLine("\nName: {0}", pet.Name);
}
}

/*
This code produces the following output:

Name: Barley
Name: Boots
Name: Whiskers

Name: Default Pet
*/

Distinct

返回序列中的非重复元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
List<int> ages = new List<int> { 21, 46, 46, 55, 17, 21, 55, 55 };

IEnumerable<int> distinctAges = ages.Distinct();

Console.WriteLine("Distinct ages:");

foreach (int age in distinctAges)
{
Console.WriteLine(age);
}

/*
This code produces the following output:

Distinct ages:
21
46
55
17
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class MyProduct : IEquatable<MyProduct>
{
public string Name { get; set; }
public int Code { get; set; }

public bool Equals(MyProduct other)
{
//Check whether the compared object is null.
if (Object.ReferenceEquals(other, null)) return false;

//Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other)) return true;

//Check whether the products' properties are equal.
return Code.Equals(other.Code) && Name.Equals(other.Name);
}

// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.

public override int GetHashCode()
{

//Get hash code for the Name field if it is not null.
int hashProductName = Name == null ? 0 : Name.GetHashCode();

//Get hash code for the Code field.
int hashProductCode = Code.GetHashCode();

//Calculate the hash code for the product.
return hashProductName ^ hashProductCode;
}
}

MyProduct[] products = { new MyProduct { Name = "apple", Code = 9 },
new MyProduct { Name = "orange", Code = 4 },
new MyProduct { Name = "apple", Code = 9 },
new MyProduct { Name = "lemon", Code = 12 } };

// Exclude duplicates.

IEnumerable<MyProduct> noduplicates =
products.Distinct();

foreach (var product in noduplicates)
Console.WriteLine(product.Name + " " + product.Code);

/*
This code produces the following output:
apple 9
orange 4
lemon 12
*/

ElementAt

返回序列中指定索引处的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string[] names =
{ "Hartono, Tommy", "Adams, Terry", "Andersen, Henriette Thaulow",

"Hedlund, Magnus", "Ito, Shu" };
Random random = new Random(DateTime.Now.Millisecond);

string name = names.ElementAt(random.Next(0, names.Length));

Console.WriteLine("The name chosen at random is '{0}'.", name);

/*
This code produces output similar to the following:

The name chosen at random is 'Ito, Shu'.
*/

ElementAtOrDefault

返回序列中指定索引处的元素;如果索引超出范围,则返回默认值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
string[] names =
{ "Hartono, Tommy", "Adams, Terry", "Andersen, Henriette Thaulow",
"Hedlund, Magnus", "Ito, Shu" };

int index = 20;

string name = names.ElementAtOrDefault(index);

Console.WriteLine(
"The name chosen at index {0} is '{1}'.",
index,
String.IsNullOrEmpty(name) ? "<no name at this index>" : name);

/*
This code produces the following output:

The name chosen at index 20 is '<no name at this index>'.
*/

Empty

返回具有指定类型参数的空 IEnumerable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
string[] names1 = { "Hartono, Tommy" };
string[] names2 = { "Adams, Terry", "Andersen, Henriette Thaulow",
"Hedlund, Magnus", "Ito, Shu" };
string[] names3 = { "Solanki, Ajay", "Hoeing, Helge",
"Andersen, Henriette Thaulow",
"Potra, Cristina", "Iallo, Lucio" };

List<string[]> namesList =
new List<string[]> { names1, names2, names3 };

// Only include arrays that have four or more elements
IEnumerable<string> allNames =
namesList.Aggregate(Enumerable.Empty<string>(),
(current, next) => next.Length > 3 ? current.Union(next) : current);

foreach (string name in allNames)
{
Console.WriteLine(name);
}

/*
This code produces the following output:

Adams, Terry
Andersen, Henriette Thaulow
Hedlund, Magnus
Ito, Shu
Solanki, Ajay
Hoeing, Helge
Potra, Cristina
Iallo, Lucio
*/

Except

生成两个序列的差集。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
double[] numbers1 = { 2.0, 2.0, 2.1, 2.2, 2.3, 2.3, 2.4, 2.5 };
double[] numbers2 = { 2.2 };

IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2);

foreach (double number in onlyInFirstSet)
Console.WriteLine(number);

/*
This code produces the following output:

2
2.1
2.3
2.4
2.5
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class ProductA : IEquatable<ProductA>
{
public string Name { get; set; }
public int Code { get; set; }

public bool Equals(ProductA other)
{
if (other is null)
return false;

return this.Name == other.Name && this.Code == other.Code;
}

public override bool Equals(object obj) => Equals(obj as ProductA);
public override int GetHashCode() => (Name, Code).GetHashCode();
}

ProductA[] fruits1 = { new ProductA { Name = "apple", Code = 9 },
new ProductA { Name = "orange", Code = 4 },
new ProductA { Name = "lemon", Code = 12 } };

ProductA[] fruits2 = { new ProductA { Name = "apple", Code = 9 } };

// Get all the elements from the first array
// except for the elements from the second array.

IEnumerable<ProductA> except =
fruits1.Except(fruits2);

foreach (var product in except)
Console.WriteLine(product.Name + " " + product.Code);

/*
This code produces the following output:

orange 4
lemon 12
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public class Product
{
public string Name { get; set; }
public int Code { get; set; }
}

// Custom comparer for the Product class
class ProductComparer : IEqualityComparer<Product>
{
// Products are equal if their names and product numbers are equal.
public bool Equals(Product x, Product y)
{

//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;

//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;

//Check whether the products' properties are equal.
return x.Code == y.Code && x.Name == y.Name;
}

// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.

public int GetHashCode(Product product)
{
//Check whether the object is null
if (Object.ReferenceEquals(product, null)) return 0;

//Get hash code for the Name field if it is not null.
int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();

//Get hash code for the Code field.
int hashProductCode = product.Code.GetHashCode();

//Calculate the hash code for the product.
return hashProductName ^ hashProductCode;
}
}

Product[] fruits1 = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 },
new Product { Name = "lemon", Code = 12 } };

Product[] fruits2 = { new Product { Name = "apple", Code = 9 } };

// Get all the elements from the first array
// except for the elements from the second array.

IEnumerable<Product> except =
fruits1.Except(fruits2, new ProductComparer());

foreach (var product in except)
Console.WriteLine(product.Name + " " + product.Code);

/*
This code produces the following output:

orange 4
lemon 12
*/

First

返回序列中的第一个元素。

1
2
3
4
5
6
7
8
9
10
11
12
int[] numbers = { 9, 34, 65, 92, 87, 435, 3, 54,
83, 23, 87, 435, 67, 12, 19 };

int first = numbers.First();

Console.WriteLine(first);

/*
This code produces the following output:

9
*/
1
2
3
4
5
6
7
8
9
10
11
12
int[] numbers = { 9, 34, 65, 92, 87, 435, 3, 54,
83, 23, 87, 435, 67, 12, 19 };

int first = numbers.First(number => number > 80);

Console.WriteLine(first);

/*
This code produces the following output:

92
*/

FirstOrDefault

返回序列中的第一个元素;如果未找到该元素,则返回默认值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
string[] names = { "Hartono, Tommy", "Adams, Terry",
"Andersen, Henriette Thaulow",
"Hedlund, Magnus", "Ito, Shu" };

string firstLongName = names.FirstOrDefault(name => name.Length > 20);

Console.WriteLine("The first long name is '{0}'.", firstLongName);

string firstVeryLongName = names.FirstOrDefault(name => name.Length > 30);

Console.WriteLine(
"There is {0} name longer than 30 characters.",
string.IsNullOrEmpty(firstVeryLongName) ? "not a" : "a");

/*
This code produces the following output:

The first long name is 'Andersen, Henriette Thaulow'.
There is not a name longer than 30 characters.
*/
1
2
3
4
5
6
7
8
9
int[] numbers = { };
int first = numbers.FirstOrDefault();
Console.WriteLine(first);

/*
This code produces the following output:

0
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
List<int> months = new List<int> { };

// Setting the default value to 1 after the query.
int firstMonth1 = months.FirstOrDefault();
if (firstMonth1 == 0)
{
firstMonth1 = 1;
}
Console.WriteLine("The value of the firstMonth1 variable is {0}", firstMonth1);

// Setting the default value to 1 by using DefaultIfEmpty() in the query.
int firstMonth2 = months.DefaultIfEmpty(1).First();
Console.WriteLine("The value of the firstMonth2 variable is {0}", firstMonth2);

/*
This code produces the following output:

The value of the firstMonth1 variable is 1
The value of the firstMonth2 variable is 1
*/

GroupBy

对序列中的元素进行分组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class Pet
{
public string Name { get; set; }
public double Age { get; set; }
}

public static void GroupByEx4()
{
// Create a list of pets.
List<Pet> petsList =
new List<Pet>{ new Pet { Name="Barley", Age=8.3 },
new Pet { Name="Boots", Age=4.9 },
new Pet { Name="Whiskers", Age=1.5 },
new Pet { Name="Daisy", Age=4.3 } };

// Group Pet.Age values by the Math.Floor of the age.
// Then project an anonymous type from each group
// that consists of the key, the count of the group's
// elements, and the minimum and maximum age in the group.
var query = petsList.GroupBy(
pet => Math.Floor(pet.Age),
pet => pet.Age,
(baseAge, ages) => new
{
Key = baseAge,
Count = ages.Count(),
Min = ages.Min(),
Max = ages.Max()
});

// Iterate over each anonymous type.
foreach (var result in query)
{
Console.WriteLine("\nAge group: " + result.Key);
Console.WriteLine("Number of pets in this age group: " + result.Count);
Console.WriteLine("Minimum age: " + result.Min);
Console.WriteLine("Maximum age: " + result.Max);
}

/* This code produces the following output:

Age group: 8
Number of pets in this age group: 1
Minimum age: 8.3
Maximum age: 8.3

Age group: 4
Number of pets in this age group: 2
Minimum age: 4.3
Maximum age: 4.9

Age group: 1
Number of pets in this age group: 1
Minimum age: 1.5
Maximum age: 1.5
*/
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}

// Uses method-based query syntax.
public static void GroupByEx1()
{
// Create a list of pets.
List<Pet> pets =
new List<Pet>{ new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 },
new Pet { Name="Daisy", Age=4 } };

// Group the pets using Age as the key value
// and selecting only the pet's Name for each value.
IEnumerable<IGrouping<int, string>> query =
pets.GroupBy(pet => pet.Age, pet => pet.Name);

// Iterate over each IGrouping in the collection.
foreach (IGrouping<int, string> petGroup in query)
{
// Print the key value of the IGrouping.
Console.WriteLine(petGroup.Key);
// Iterate over each value in the
// IGrouping and print the value.
foreach (string name in petGroup)
Console.WriteLine(" {0}", name);
}
}

/*
This code produces the following output:

8
Barley
4
Boots
Daisy
1
Whiskers
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class Pet
{
public string Name { get; set; }
public double Age { get; set; }
}

public static void GroupByEx3()
{
// Create a list of pets.
List<Pet> petsList =
new List<Pet>{ new Pet { Name="Barley", Age=8.3 },
new Pet { Name="Boots", Age=4.9 },
new Pet { Name="Whiskers", Age=1.5 },
new Pet { Name="Daisy", Age=4.3 } };

// Group Pet objects by the Math.Floor of their age.
// Then project an anonymous type from each group
// that consists of the key, the count of the group's
// elements, and the minimum and maximum age in the group.
var query = petsList.GroupBy(
pet => Math.Floor(pet.Age),
(age, pets) => new
{
Key = age,
Count = pets.Count(),
Min = pets.Min(pet => pet.Age),
Max = pets.Max(pet => pet.Age)
});

// Iterate over each anonymous type.
foreach (var result in query)
{
Console.WriteLine("\nAge group: " + result.Key);
Console.WriteLine("Number of pets in this age group: " + result.Count);
Console.WriteLine("Minimum age: " + result.Min);
Console.WriteLine("Maximum age: " + result.Max);
}

/* This code produces the following output:

Age group: 8
Number of pets in this age group: 1
Minimum age: 8.3
Maximum age: 8.3

Age group: 4
Number of pets in this age group: 2
Minimum age: 4.3
Maximum age: 4.9

Age group: 1
Number of pets in this age group: 1
Minimum age: 1.5
Maximum age: 1.5
*/
}

GroupJoin

基于键值等同性将两个序列的元素进行关联,并对结果进行分组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class Person
{
public string Name { get; set; }
}

class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}

public static void GroupJoinEx1()
{
Person magnus = new Person { Name = "Hedlund, Magnus" };
Person terry = new Person { Name = "Adams, Terry" };
Person charlotte = new Person { Name = "Weiss, Charlotte" };

Pet barley = new Pet { Name = "Barley", Owner = terry };
Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

List<Person> people = new List<Person> { magnus, terry, charlotte };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy };

// Create a list where each element is an anonymous
// type that contains a person's name and
// a collection of names of the pets they own.
var query =
people.GroupJoin(pets,
person => person,
pet => pet.Owner,
(person, petCollection) =>
new
{
OwnerName = person.Name,
Pets = petCollection.Select(pet => pet.Name)
});

foreach (var obj in query)
{
// Output the owner's name.
Console.WriteLine("{0}:", obj.OwnerName);
// Output each of the owner's pet's names.
foreach (string pet in obj.Pets)
{
Console.WriteLine(" {0}", pet);
}
}
}

/*
This code produces the following output:

Hedlund, Magnus:
Daisy
Adams, Terry:
Barley
Boots
Weiss, Charlotte:
Whiskers
*/

Intersect

生成两个序列的交集。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int[] id1 = { 44, 26, 92, 30, 71, 38 };
int[] id2 = { 39, 59, 83, 47, 26, 4, 30 };

IEnumerable<int> both = id1.Intersect(id2);

foreach (int id in both)
Console.WriteLine(id);

/*
This code produces the following output:

26
30
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class ProductA : IEquatable<ProductA>
{
public string Name { get; set; }
public int Code { get; set; }

public bool Equals(ProductA other)
{
if (other is null)
return false;

return this.Name == other.Name && this.Code == other.Code;
}

public override bool Equals(object obj) => Equals(obj as ProductA);
public override int GetHashCode() => (Name, Code).GetHashCode();
}

ProductA[] store1 = { new ProductA { Name = "apple", Code = 9 },
new ProductA { Name = "orange", Code = 4 } };

ProductA[] store2 = { new ProductA { Name = "apple", Code = 9 },
new ProductA { Name = "lemon", Code = 12 } };

// Get the products from the first array
// that have duplicates in the second array.

IEnumerable<ProductA> duplicates =
store1.Intersect(store2);

foreach (var product in duplicates)
Console.WriteLine(product.Name + " " + product.Code);

/*
This code produces the following output:
apple 9
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class Product
{
public string Name { get; set; }
public int Code { get; set; }
}

// Custom comparer for the Product class
class ProductComparer : IEqualityComparer<Product>
{
// Products are equal if their names and product numbers are equal.
public bool Equals(Product x, Product y)
{

//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;

//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;

//Check whether the products' properties are equal.
return x.Code == y.Code && x.Name == y.Name;
}

// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.

public int GetHashCode(Product product)
{
//Check whether the object is null
if (Object.ReferenceEquals(product, null)) return 0;

//Get hash code for the Name field if it is not null.
int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();

//Get hash code for the Code field.
int hashProductCode = product.Code.GetHashCode();

//Calculate the hash code for the product.
return hashProductName ^ hashProductCode;
}
}

Product[] store1 = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 } };

Product[] store2 = { new Product { Name = "apple", Code = 9 },
new Product { Name = "lemon", Code = 12 } };

// Get the products from the first array
// that have duplicates in the second array.

IEnumerable<Product> duplicates =
store1.Intersect(store2, new ProductComparer());

foreach (var product in duplicates)
Console.WriteLine(product.Name + " " + product.Code);

/*
This code produces the following output:
apple 9
*/

Join

基于匹配键对两个序列的元素进行关联。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class Person
{
public string Name { get; set; }
}

class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}

public static void JoinEx1()
{
Person magnus = new Person { Name = "Hedlund, Magnus" };
Person terry = new Person { Name = "Adams, Terry" };
Person charlotte = new Person { Name = "Weiss, Charlotte" };

Pet barley = new Pet { Name = "Barley", Owner = terry };
Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

List<Person> people = new List<Person> { magnus, terry, charlotte };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, daisy };

// Create a list of Person-Pet pairs where
// each element is an anonymous type that contains a
// Pet's name and the name of the Person that owns the Pet.
var query =
people.Join(pets,
person => person,
pet => pet.Owner,
(person, pet) =>
new { OwnerName = person.Name, Pet = pet.Name });

foreach (var obj in query)
{
Console.WriteLine(
"{0} - {1}",
obj.OwnerName,
obj.Pet);
}
}

/*
This code produces the following output:

Hedlund, Magnus - Daisy
Adams, Terry - Barley
Adams, Terry - Boots
Weiss, Charlotte - Whiskers
*/

Last

返回序列的最后一个元素。

1
2
3
4
5
6
7
8
9
10
11
12
int[] numbers = { 9, 34, 65, 92, 87, 435, 3, 54,
83, 23, 87, 67, 12, 19 };

int last = numbers.Last();

Console.WriteLine(last);

/*
This code produces the following output:

19
*/
1
2
3
4
5
6
7
8
9
10
11
12
int[] numbers = { 9, 34, 65, 92, 87, 435, 3, 54,
83, 23, 87, 67, 12, 19 };

int last = numbers.Last(num => num > 80);

Console.WriteLine(last);

/*
This code produces the following output:

87
*/

LastOrDefault

返回序列中的最后一个元素;如果未找到该元素,则返回默认值。

1
2
3
4
5
6
7
8
9
10
string[] fruits = { };
string last = fruits.LastOrDefault();
Console.WriteLine(
String.IsNullOrEmpty(last) ? "<string is null or empty>" : last);

/*
This code produces the following output:

<string is null or empty>
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
List<int> daysOfMonth = new List<int> { };

// Setting the default value to 1 after the query.
int lastDay1 = daysOfMonth.LastOrDefault();
if (lastDay1 == 0)
{
lastDay1 = 1;
}
Console.WriteLine("The value of the lastDay1 variable is {0}", lastDay1);

// Setting the default value to 1 by using DefaultIfEmpty() in the query.
int lastDay2 = daysOfMonth.DefaultIfEmpty(1).Last();
Console.WriteLine("The value of the lastDay2 variable is {0}", lastDay2);

/*
This code produces the following output:

The value of the lastDay1 variable is 1
The value of the lastDay2 variable is 1
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
double[] numbers = { 49.6, 52.3, 51.0, 49.4, 50.2, 48.3 };

double last50 = numbers.LastOrDefault(n => Math.Round(n) == 50.0);

Console.WriteLine("The last number that rounds to 50 is {0}.", last50);

double last40 = numbers.LastOrDefault(n => Math.Round(n) == 40.0);

Console.WriteLine(
"The last number that rounds to 40 is {0}.",
last40 == 0.0 ? "<DOES NOT EXIST>" : last40.ToString());

/*
This code produces the following output:

The last number that rounds to 50 is 50.2.
The last number that rounds to 40 is <DOES NOT EXIST>.
*/

LongCount

返回表示序列中的元素数量的 Int64。

1
2
3
4
5
6
7
8
9
10
11
12
string[] fruits = { "apple", "banana", "mango",
"orange", "passionfruit", "grape" };

long count = fruits.LongCount();

Console.WriteLine("There are {0} fruits in the collection.", count);

/*
This code produces the following output:

There are 6 fruits in the collection.
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}

public static void LongCountEx2()
{
Pet[] pets = { new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };

const int Age = 3;

long count = pets.LongCount(pet => pet.Age > Age);

Console.WriteLine("There are {0} animals over age {1}.", count, Age);
}

/*
This code produces the following output:

There are 2 animals over age 3.
*/

Max

返回值序列中的最大值。

1
2
3
4
5
6
7
8
9
10
11
double?[] doubles = { null, 1.5E+104, 9E+103, -2E+103 };

double? max = doubles.Max();

Console.WriteLine("The largest number is {0}.", max);

/*
This code produces the following output:

The largest number is 1.5E+104.
*/
1
2
3
4
5
6
7
8
9
10
11
List<long> longs = new List<long> { 4294967296L, 466855135L, 81125L };

long max = longs.Max();

Console.WriteLine("The largest number is {0}.", max);

/*
This code produces the following output:

The largest number is 4294967296.
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}

public static void MaxEx4()
{
Pet[] pets = { new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };

int max = pets.Max(pet => pet.Age + pet.Name.Length);

Console.WriteLine(
"The maximum pet age plus name length is {0}.",
max);
}

/*
This code produces the following output:

The maximum pet age plus name length is 14.
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/// <summary>
/// This class implements IComparable to be able to
/// compare one Pet to another Pet.
/// </summary>
class Pet : IComparable<Pet>
{
public string Name { get; set; }
public int Age { get; set; }

/// <summary>
/// Compares this Pet to another Pet by
/// summing each Pet's age and name length.
/// </summary>
/// <param name="other">The Pet to compare this Pet to.</param>
/// <returns>-1 if this Pet is 'less' than the other Pet,
/// 0 if they are equal,
/// or 1 if this Pet is 'greater' than the other Pet.</returns>
int IComparable<Pet>.CompareTo(Pet other)
{
int sumOther = other.Age + other.Name.Length;
int sumThis = this.Age + this.Name.Length;

if (sumOther > sumThis)
return -1;
else if (sumOther == sumThis)
return 0;
else
return 1;
}
}

public static void MaxEx3()
{
Pet[] pets = { new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };

Pet max = pets.Max();

Console.WriteLine(
"The 'maximum' animal is {0}.",
max.Name);
}

/*
This code produces the following output:

The 'maximum' animal is Barley.
*/

Min

返回值序列中的最小值。

1
2
3
4
5
6
7
8
9
10
11
int?[] grades = { 78, 92, null, 99, 37, 81 };

int? min = grades.Min();

Console.WriteLine("The lowest grade is {0}.", min);

/*
This code produces the following output:

The lowest grade is 37.
*/
1
2
3
4
5
6
7
8
9
10
11
double[] doubles = { 1.5E+104, 9E+103, -2E+103 };

double min = doubles.Min();

Console.WriteLine("The smallest number is {0}.", min);

/*
This code produces the following output:

The smallest number is -2E+103.
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}

public static void MinEx4()
{
Pet[] pets = { new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };

int min = pets.Min(pet => pet.Age);

Console.WriteLine("The youngest animal is age {0}.", min);
}

/*
This code produces the following output:

The youngest animal is age 1.
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/// <summary>
/// This class implements IComparable in order to
/// be able to compare different Pet objects.
/// </summary>
class Pet : IComparable<Pet>
{
public string Name { get; set; }
public int Age { get; set; }

/// <summary>
/// Compares this Pet's age to another Pet's age.
/// </summary>
/// <param name="other">The Pet to compare this Pet to.</param>
/// <returns>-1 if this Pet's age is smaller,
/// 0 if the Pets' ages are equal, or
/// 1 if this Pet's age is greater.</returns>
int IComparable<Pet>.CompareTo(Pet other)
{
if (other.Age > this.Age)
return -1;
else if (other.Age == this.Age)
return 0;
else
return 1;
}
}

public static void MinEx3()
{
Pet[] pets = { new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };

Pet min = pets.Min();

Console.WriteLine(
"The 'minimum' animal is {0}.",
min.Name);
}

/*
This code produces the following output:

The 'minimum' animal is Whiskers.
*/

OfType

根据指定类型筛选 IEnumerable 的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
System.Collections.ArrayList fruits = new()
{
"Mango",
"Orange",
null,
"Apple",
3.0,
"Banana"
};

// Apply OfType() to the ArrayList.
IEnumerable<string> query1 = fruits.OfType<string>();

Console.WriteLine("Elements of type 'string' are:");
foreach (string fruit in query1)
{
Console.WriteLine(fruit);
}

// The following query shows that the standard query operators such as
// Where() can be applied to the ArrayList type after calling OfType().
IEnumerable<string> query2 =
fruits.OfType<string>().Where(fruit =>
fruit.Contains('n', StringComparison.CurrentCultureIgnoreCase));

Console.WriteLine("\nThe following strings contain 'n':");
foreach (string fruit in query2)
{
Console.WriteLine(fruit);
}

// This code produces the following output:
//
// Elements of type 'string' are:
// Mango
// Orange
// Apple
// Banana
//
// The following strings contain 'n':
// Mango
// Orange
// Banana

OrderBy

按升序对序列的元素进行排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}

public static void OrderByEx1()
{
Pet[] pets = { new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 } };

IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age);

foreach (Pet pet in query)
{
Console.WriteLine("{0} - {1}", pet.Name, pet.Age);
}
}

/*
This code produces the following output:

Whiskers - 1
Boots - 4
Barley - 8
*/

OrderByDescending

按降序对序列的元素排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/// <summary>
/// This IComparer class sorts by the fractional part of the decimal number.
/// </summary>
public class SpecialComparer : IComparer<decimal>
{
/// <summary>
/// Compare two decimal numbers by their fractional parts.
/// </summary>
/// <param name="d1">The first decimal to compare.</param>
/// <param name="d2">The second decimal to compare.</param>
/// <returns>1 if the first decimal's fractional part
/// is greater than the second decimal's fractional part,
/// -1 if the first decimal's fractional
/// part is less than the second decimal's fractional part,
/// or the result of calling Decimal.Compare()
/// if the fractional parts are equal.</returns>
public int Compare(decimal d1, decimal d2)
{
decimal fractional1, fractional2;

// Get the fractional part of the first number.
try
{
fractional1 = decimal.Remainder(d1, decimal.Floor(d1));
}
catch (DivideByZeroException)
{
fractional1 = d1;
}
// Get the fractional part of the second number.
try
{
fractional2 = decimal.Remainder(d2, decimal.Floor(d2));
}
catch (DivideByZeroException)
{
fractional2 = d2;
}

if (fractional1 == fractional2)
return Decimal.Compare(d1, d2);
else if (fractional1 > fractional2)
return 1;
else
return -1;
}
}

public static void OrderByDescendingEx1()
{
List<decimal> decimals =
new List<decimal> { 6.2m, 8.3m, 0.5m, 1.3m, 6.3m, 9.7m };

IEnumerable<decimal> query =
decimals.OrderByDescending(num =>
num, new SpecialComparer());

foreach (decimal num in query)
{
Console.WriteLine(num);
}
}

/*
This code produces the following output:

9.7
0.5
8.3
6.3
1.3
6.2
*/

Range

生成指定范围内的整数的序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Generate a sequence of integers from 1 to 10
// and then select their squares.
IEnumerable<int> squares = Enumerable.Range(1, 10).Select(x => x * x);

foreach (int num in squares)
{
Console.WriteLine(num);
}

/*
This code produces the following output:

1
4
9
16
25
36
49
64
81
100
*/

Repeat

生成包含一个重复值的序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
IEnumerable<string> strings =
Enumerable.Repeat("I like programming.", 15);

foreach (String str in strings)
{
Console.WriteLine(str);
}

/*
This code produces the following output:

I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
I like programming.
*/

Reverse

反转序列中元素的顺序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char[] apple = { 'a', 'p', 'p', 'l', 'e' };

char[] reversed = apple.Reverse().ToArray();

foreach (char chr in reversed)
{
Console.Write(chr + " ");
}
Console.WriteLine();

/*
This code produces the following output:

e l p p a
*/

Select

将序列中的每个元素投影到新表单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
string[] fruits = { "apple", "banana", "mango", "orange",
"passionfruit", "grape" };

var query =
fruits.Select((fruit, index) =>
new { index, str = fruit.Substring(0, index) });

foreach (var obj in query)
{
Console.WriteLine("{0}", obj);
}

/*
This code produces the following output:

{ index = 0, str = }
{ index = 1, str = b }
{ index = 2, str = ma }
{ index = 3, str = ora }
{ index = 4, str = pass }
{ index = 5, str = grape }
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
IEnumerable<int> squares =
Enumerable.Range(1, 10).Select(x => x * x);

foreach (int num in squares)
{
Console.WriteLine(num);
}
/*
This code produces the following output:

1
4
9
16
25
36
49
64
81
100
*/

SelectMany

将序列的每个元素投影到 IEnumerable 并将结果序列合并为一个序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class PetOwner
{
public string Name { get; set; }
public List<string> Pets { get; set; }
}

public static void SelectManyEx3()
{
PetOwner[] petOwners =
{ new PetOwner { Name="Higa",
Pets = new List<string>{ "Scruffy", "Sam" } },
new PetOwner { Name="Ashkenazi",
Pets = new List<string>{ "Walker", "Sugar" } },
new PetOwner { Name="Price",
Pets = new List<string>{ "Scratches", "Diesel" } },
new PetOwner { Name="Hines",
Pets = new List<string>{ "Dusty" } } };

// Project the pet owner's name and the pet's name.
var query =
petOwners
.SelectMany(petOwner => petOwner.Pets, (petOwner, petName) => new { petOwner, petName })
.Where(ownerAndPet => ownerAndPet.petName.StartsWith("S"))
.Select(ownerAndPet =>
new
{
Owner = ownerAndPet.petOwner.Name,
Pet = ownerAndPet.petName
}
);

// Print the results.
foreach (var obj in query)
{
Console.WriteLine(obj);
}
}

// This code produces the following output:
//
// {Owner=Higa, Pet=Scruffy}
// {Owner=Higa, Pet=Sam}
// {Owner=Ashkenazi, Pet=Sugar}
// {Owner=Price, Pet=Scratches}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class PetOwner
{
public string Name { get; set; }
public List<String> Pets { get; set; }
}

public static void SelectManyEx1()
{
PetOwner[] petOwners =
{ new PetOwner { Name="Higa, Sidney",
Pets = new List<string>{ "Scruffy", "Sam" } },
new PetOwner { Name="Ashkenazi, Ronen",
Pets = new List<string>{ "Walker", "Sugar" } },
new PetOwner { Name="Price, Vernette",
Pets = new List<string>{ "Scratches", "Diesel" } } };

// Query using SelectMany().
IEnumerable<string> query1 = petOwners.SelectMany(petOwner => petOwner.Pets);

Console.WriteLine("Using SelectMany():");

// Only one foreach loop is required to iterate
// through the results since it is a
// one-dimensional collection.
foreach (string pet in query1)
{
Console.WriteLine(pet);
}

// This code shows how to use Select()
// instead of SelectMany().
IEnumerable<List<String>> query2 =
petOwners.Select(petOwner => petOwner.Pets);

Console.WriteLine("\nUsing Select():");

// Notice that two foreach loops are required to
// iterate through the results
// because the query returns a collection of arrays.
foreach (List<String> petList in query2)
{
foreach (string pet in petList)
{
Console.WriteLine(pet);
}
Console.WriteLine();
}
}

/*
This code produces the following output:

Using SelectMany():
Scruffy
Sam
Walker
Sugar
Scratches
Diesel

Using Select():
Scruffy
Sam

Walker
Sugar

Scratches
Diesel
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class PetOwner
{
public string Name { get; set; }
public List<string> Pets { get; set; }
}

public static void SelectManyEx2()
{
PetOwner[] petOwners =
{ new PetOwner { Name="Higa, Sidney",
Pets = new List<string>{ "Scruffy", "Sam" } },
new PetOwner { Name="Ashkenazi, Ronen",
Pets = new List<string>{ "Walker", "Sugar" } },
new PetOwner { Name="Price, Vernette",
Pets = new List<string>{ "Scratches", "Diesel" } },
new PetOwner { Name="Hines, Patrick",
Pets = new List<string>{ "Dusty" } } };

// Project the items in the array by appending the index
// of each PetOwner to each pet's name in that petOwner's
// array of pets.
IEnumerable<string> query =
petOwners.SelectMany((petOwner, index) =>
petOwner.Pets.Select(pet => index + pet));

foreach (string pet in query)
{
Console.WriteLine(pet);
}
}

// This code produces the following output:
//
// 0Scruffy
// 0Sam
// 1Walker
// 1Sugar
// 2Scratches
// 2Diesel
// 3Dusty

SequenceEqual

根据相等比较器确定两个序列是否相等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}

public static void SequenceEqualEx1()
{
Pet pet1 = new Pet { Name = "Turbo", Age = 2 };
Pet pet2 = new Pet { Name = "Peanut", Age = 8 };

// Create two lists of pets.
List<Pet> pets1 = new List<Pet> { pet1, pet2 };
List<Pet> pets2 = new List<Pet> { pet1, pet2 };

bool equal = pets1.SequenceEqual(pets2);

Console.WriteLine(
"The lists {0} equal.",
equal ? "are" : "are not");
}

/*
This code produces the following output:

The lists are equal.
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Pet
{
public string Name { get; set; }
public int Age { get; set; }
}

public static void SequenceEqualEx2()
{
Pet pet1 = new Pet() { Name = "Turbo", Age = 2 };
Pet pet2 = new Pet() { Name = "Peanut", Age = 8 };

// Create two lists of pets.
List<Pet> pets1 = new List<Pet> { pet1, pet2 };
List<Pet> pets2 =
new List<Pet> { new Pet { Name = "Turbo", Age = 2 },
new Pet { Name = "Peanut", Age = 8 } };

bool equal = pets1.SequenceEqual(pets2);

Console.WriteLine("The lists {0} equal.", equal ? "are" : "are not");
}

/*
序列包含相同的数据,但由于它们包含的对象具有不同的引用,因此序列不被视为相等。
This code produces the following output:

The lists are not equal.
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class ProductA : IEquatable<ProductA>
{
public string Name { get; set; }
public int Code { get; set; }

public bool Equals(ProductA other)
{
if (other is null)
return false;

return this.Name == other.Name && this.Code == other.Code;
}

public override bool Equals(object obj) => Equals(obj as ProductA);
public override int GetHashCode() => (Name, Code).GetHashCode();
}

ProductA[] storeA = { new ProductA { Name = "apple", Code = 9 },
new ProductA { Name = "orange", Code = 4 } };

ProductA[] storeB = { new ProductA { Name = "apple", Code = 9 },
new ProductA { Name = "orange", Code = 4 } };

bool equalAB = storeA.SequenceEqual(storeB);

Console.WriteLine("Equal? " + equalAB);

/*
This code produces the following output:

Equal? True
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class Product
{
public string Name { get; set; }
public int Code { get; set; }
}

// Custom comparer for the Product class
class ProductComparer : IEqualityComparer<Product>
{
// Products are equal if their names and product numbers are equal.
public bool Equals(Product x, Product y)
{

//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;

//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;

//Check whether the products' properties are equal.
return x.Code == y.Code && x.Name == y.Name;
}

// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.

public int GetHashCode(Product product)
{
//Check whether the object is null
if (Object.ReferenceEquals(product, null)) return 0;

//Get hash code for the Name field if it is not null.
int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();

//Get hash code for the Code field.
int hashProductCode = product.Code.GetHashCode();

//Calculate the hash code for the product.
return hashProductName ^ hashProductCode;
}
}

Product[] storeA = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 } };

Product[] storeB = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 } };

bool equalAB = storeA.SequenceEqual(storeB, new ProductComparer());

Console.WriteLine("Equal? " + equalAB);

/*
This code produces the following output:

Equal? True
*/

Single

返回序列中的单个特定元素。

1
2
3
4
5
6
7
8
9
10
11
12
string[] fruits = { "apple", "banana", "mango",
"orange", "passionfruit", "grape" };

string fruit1 = fruits.Single(fruit => fruit.Length > 10);

Console.WriteLine(fruit1);

/*
This code produces the following output:

passionfruit
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
string fruit2 = null;

try
{
fruit2 = fruits.Single(fruit => fruit.Length > 15);
}
catch (System.InvalidOperationException)
{
Console.WriteLine(@"The collection does not contain exactly
one element whose length is greater than 15.");
}

Console.WriteLine(fruit2);

// This code produces the following output:
//
// The collection does not contain exactly
// one element whose length is greater than 15.
1
2
3
4
5
6
7
8
9
10
11
string[] fruits1 = { "orange" };

string fruit1 = fruits1.Single();

Console.WriteLine(fruit1);

/*
This code produces the following output:

orange
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
string[] fruits2 = { "orange", "apple" };
string fruit2 = null;

try
{
fruit2 = fruits2.Single();
}
catch (System.InvalidOperationException)
{
Console.WriteLine("The collection does not contain exactly one element.");
}

Console.WriteLine(fruit2);

/*
This code produces the following output:

The collection does not contain exactly one element.
*/

SingleOrDefault

返回序列中的单个特定元素;如果未找到该元素,则返回默认值。

1
2
3
4
5
6
7
8
9
10
11
string[] fruits1 = { "orange" };

string fruit1 = fruits1.SingleOrDefault();

Console.WriteLine(fruit1);

/*
This code produces the following output:

orange
*/
1
2
3
4
5
6
7
8
9
10
11
12
string[] fruits2 = { };

string fruit2 = fruits2.SingleOrDefault();

Console.WriteLine(
String.IsNullOrEmpty(fruit2) ? "No such string!" : fruit2);

/*
This code produces the following output:

No such string!
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int[] pageNumbers = { };

// Setting the default value to 1 after the query.
int pageNumber1 = pageNumbers.SingleOrDefault();
if (pageNumber1 == 0)
{
pageNumber1 = 1;
}
Console.WriteLine("The value of the pageNumber1 variable is {0}", pageNumber1);

// Setting the default value to 1 by using DefaultIfEmpty() in the query.
int pageNumber2 = pageNumbers.DefaultIfEmpty(1).Single();
Console.WriteLine("The value of the pageNumber2 variable is {0}", pageNumber2);

/*
This code produces the following output:

The value of the pageNumber1 variable is 1
The value of the pageNumber2 variable is 1
*/
1
2
3
4
5
6
7
8
9
10
11
12
string[] fruits = { "apple", "banana", "mango",
"orange", "passionfruit", "grape" };

string fruit1 = fruits.SingleOrDefault(fruit => fruit.Length > 10);

Console.WriteLine(fruit1);

/*
This code produces the following output:

passionfruit
*/
1
2
3
4
5
6
7
8
9
10
11
string fruit2 =
fruits.SingleOrDefault(fruit => fruit.Length > 15);

Console.WriteLine(
String.IsNullOrEmpty(fruit2) ? "No such string!" : fruit2);

/*
This code produces the following output:

No such string!
*/

Skip

跳过序列中指定数量的元素,然后返回剩余的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int[] grades = { 59, 82, 70, 56, 92, 98, 85 };

Console.WriteLine("All grades except the first three:");
foreach (int grade in grades.Skip(3))
{
Console.WriteLine(grade);
}

/*
This code produces the following output:

All grades except the first three:
56
92
98
85
*/

SkipWhile

如果指定的条件为 true,则跳过序列中的元素,然后返回剩余的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int[] grades = { 59, 82, 70, 56, 92, 98, 85 };

IEnumerable<int> lowerGrades =
grades
.OrderByDescending(grade => grade)
.SkipWhile(grade => grade >= 80);

Console.WriteLine("All grades below 80:");
foreach (int grade in lowerGrades)
{
Console.WriteLine(grade);
}

/*
This code produces the following output:

All grades below 80:
70
59
56
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int[] amounts = { 5000, 2500, 9000, 8000,
6500, 4000, 1500, 5500 };

IEnumerable<int> query =
amounts.SkipWhile((amount, index) => amount > index * 1000);

foreach (int amount in query)
{
Console.WriteLine(amount);
}

/*
This code produces the following output:

4000
1500
5500
*/

Sum

计算数值序列的和。

1
2
3
4
5
6
7
8
9
10
11
List<float> numbers = new List<float> { 43.68F, 1.25F, 583.7F, 6.5F };

float sum = numbers.Sum();

Console.WriteLine("The sum of the numbers is {0}.", sum);

/*
This code produces the following output:

The sum of the numbers is 635.13.
*/
1
2
3
4
5
6
7
8
9
10
11
float?[] points = { null, 0, 92.83F, null, 100.0F, 37.46F, 81.1F };

float? sum = points.Sum();

Console.WriteLine("Total points earned: {0}", sum);

/*
This code produces the following output:

Total points earned: 311.39
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Package
{
public string Company { get; set; }
public double Weight { get; set; }
}

public static void SumEx1()
{
List<Package> packages =
new List<Package>
{ new Package { Company = "Coho Vineyard", Weight = 25.2 },
new Package { Company = "Lucerne Publishing", Weight = 18.7 },
new Package { Company = "Wingtip Toys", Weight = 6.0 },
new Package { Company = "Adventure Works", Weight = 33.8 } };

double totalWeight = packages.Sum(pkg => pkg.Weight);

Console.WriteLine("The total weight of the packages is: {0}", totalWeight);
}

/*
This code produces the following output:

The total weight of the packages is: 83.7
*/

Take

从序列的开头返回指定数量的相邻元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int[] grades = { 59, 82, 70, 56, 92, 98, 85 };

IEnumerable<int> topThreeGrades =
grades.OrderByDescending(grade => grade).Take(3);

Console.WriteLine("The top three grades are:");
foreach (int grade in topThreeGrades)
{
Console.WriteLine(grade);
}
/*
This code produces the following output:

The top three grades are:
98
92
85
*/

TakeWhile

如果指定的条件为 true,则返回序列中的元素,然后跳过剩余的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
string[] fruits = { "apple", "passionfruit", "banana", "mango",
"orange", "blueberry", "grape", "strawberry" };

IEnumerable<string> query =
fruits.TakeWhile((fruit, index) => fruit.Length >= index);

foreach (string fruit in query)
{
Console.WriteLine(fruit);
}

/*
This code produces the following output:

apple
passionfruit
banana
mango
orange
blueberry
*/

ThenBy

按升序对序列中的元素执行后续排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
string[] fruits = { "grape", "passionfruit", "banana", "mango",
"orange", "raspberry", "apple", "blueberry" };

// Sort the strings first by their length and then
//alphabetically by passing the identity selector function.
IEnumerable<string> query =
fruits.OrderBy(fruit => fruit.Length).ThenBy(fruit => fruit);

foreach (string fruit in query)
{
Console.WriteLine(fruit);
}

/*
This code produces the following output:

apple
grape
mango
banana
orange
blueberry
raspberry
passionfruit
*/

ThenByDescending

按降序对序列中的元素执行后续排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class CaseInsensitiveComparer : IComparer<string>
{
public int Compare(string x, string y)
{
return string.Compare(x, y, true);
}
}

public static void ThenByDescendingEx1()
{
string[] fruits = { "apPLe", "baNanA", "apple", "APple", "orange", "BAnana", "ORANGE", "apPLE" };

// Sort the strings first ascending by their length and
// then descending using a custom case insensitive comparer.
IEnumerable<string> query =
fruits
.OrderBy(fruit => fruit.Length)
.ThenByDescending(fruit => fruit, new CaseInsensitiveComparer());

foreach (string fruit in query)
{
Console.WriteLine(fruit);
}
}

/*
This code produces the following output:

apPLe
apple
APple
apPLE
orange
ORANGE
baNanA
BAnana
*/

ToArray

从 IEnumerable 中创建数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Package
{
public string Company { get; set; }
public double Weight { get; set; }
}

public static void ToArrayEx1()
{
List<Package> packages =
new List<Package>
{ new Package { Company = "Coho Vineyard", Weight = 25.2 },
new Package { Company = "Lucerne Publishing", Weight = 18.7 },
new Package { Company = "Wingtip Toys", Weight = 6.0 },
new Package { Company = "Adventure Works", Weight = 33.8 } };

string[] companies = packages.Select(pkg => pkg.Company).ToArray();

foreach (string company in companies)
{
Console.WriteLine(company);
}
}

/*
This code produces the following output:

Coho Vineyard
Lucerne Publishing
Wingtip Toys
Adventure Works
*/

ToDictionary

从 IEnumerable 创建一个 Dictionary<TKey,TValue>。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Package
{
public string Company { get; set; }
public double Weight { get; set; }
public long TrackingNumber { get; set; }
}

public static void ToDictionaryEx1()
{
List<Package> packages =
new List<Package>
{ new Package { Company = "Coho Vineyard", Weight = 25.2, TrackingNumber = 89453312L },
new Package { Company = "Lucerne Publishing", Weight = 18.7, TrackingNumber = 89112755L },
new Package { Company = "Wingtip Toys", Weight = 6.0, TrackingNumber = 299456122L },
new Package { Company = "Adventure Works", Weight = 33.8, TrackingNumber = 4665518773L } };

// Create a Dictionary of Package objects,
// using TrackingNumber as the key.
Dictionary<long, Package> dictionary =
packages.ToDictionary(p => p.TrackingNumber);

foreach (KeyValuePair<long, Package> kvp in dictionary)
{
Console.WriteLine(
"Key {0}: {1}, {2} pounds",
kvp.Key,
kvp.Value.Company,
kvp.Value.Weight);
}
}

/*
This code produces the following output:

Key 89453312: Coho Vineyard, 25.2 pounds
Key 89112755: Lucerne Publishing, 18.7 pounds
Key 299456122: Wingtip Toys, 6 pounds
Key 4665518773: Adventure Works, 33.8 pounds
*/

ToList

从 IEnumerable 创建一个 List

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
string[] fruits = { "apple", "passionfruit", "banana", "mango",
"orange", "blueberry", "grape", "strawberry" };

List<int> lengths = fruits.Select(fruit => fruit.Length).ToList();

foreach (int length in lengths)
{
Console.WriteLine(length);
}

/*
This code produces the following output:

5
12
6
5
6
9
5
10
*/

ToLookup

从 IEnumerable 生成一个泛型 Lookup<TKey,TElement>。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class Package
{
public string Company { get; set; }
public double Weight { get; set; }
public long TrackingNumber { get; set; }
}

public static void ToLookupEx1()
{
// Create a list of Packages.
List<Package> packages =
new List<Package>
{ new Package { Company = "Coho Vineyard",
Weight = 25.2, TrackingNumber = 89453312L },
new Package { Company = "Lucerne Publishing",
Weight = 18.7, TrackingNumber = 89112755L },
new Package { Company = "Wingtip Toys",
Weight = 6.0, TrackingNumber = 299456122L },
new Package { Company = "Contoso Pharmaceuticals",
Weight = 9.3, TrackingNumber = 670053128L },
new Package { Company = "Wide World Importers",
Weight = 33.8, TrackingNumber = 4665518773L } };

// Create a Lookup to organize the packages.
// Use the first character of Company as the key value.
// Select Company appended to TrackingNumber
// as the element values of the Lookup.
ILookup<char, string> lookup =
packages
.ToLookup(p => p.Company[0],
p => p.Company + " " + p.TrackingNumber);

// Iterate through each IGrouping in the Lookup.
foreach (IGrouping<char, string> packageGroup in lookup)
{
// Print the key value of the IGrouping.
Console.WriteLine(packageGroup.Key);
// Iterate through each value in the
// IGrouping and print its value.
foreach (string str in packageGroup)
Console.WriteLine(" {0}", str);
}
}

/*
This code produces the following output:

C
Coho Vineyard 89453312
Contoso Pharmaceuticals 670053128
L
Lucerne Publishing 89112755
W
Wingtip Toys 299456122
Wide World Importers 4665518773
*/

Union

生成两个序列的并集。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int[] ints1 = { 5, 3, 9, 7, 5, 9, 3, 7 };
int[] ints2 = { 8, 3, 6, 4, 4, 9, 1, 0 };

IEnumerable<int> union = ints1.Union(ints2);

foreach (int num in union)
{
Console.Write("{0} ", num);
}

/*
This code produces the following output:

5 3 9 7 8 6 4 1 0
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class ProductA : IEquatable<ProductA>
{
public string Name { get; set; }
public int Code { get; set; }

public bool Equals(ProductA other)
{
if (other is null)
return false;

return this.Name == other.Name && this.Code == other.Code;
}

public override bool Equals(object obj) => Equals(obj as ProductA);
public override int GetHashCode() => (Name, Code).GetHashCode();
}

ProductA[] store1 = { new ProductA { Name = "apple", Code = 9 },
new ProductA { Name = "orange", Code = 4 } };

ProductA[] store2 = { new ProductA { Name = "apple", Code = 9 },
new ProductA { Name = "lemon", Code = 12 } };

//Get the products from the both arrays
//excluding duplicates.

IEnumerable<ProductA> union =
store1.Union(store2);

foreach (var product in union)
Console.WriteLine(product.Name + " " + product.Code);

/*
This code produces the following output:

apple 9
orange 4
lemon 12
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public class Product
{
public string Name { get; set; }
public int Code { get; set; }
}

// Custom comparer for the Product class
class ProductComparer : IEqualityComparer<Product>
{
// Products are equal if their names and product numbers are equal.
public bool Equals(Product x, Product y)
{

//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;

//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;

//Check whether the products' properties are equal.
return x.Code == y.Code && x.Name == y.Name;
}

// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.

public int GetHashCode(Product product)
{
//Check whether the object is null
if (Object.ReferenceEquals(product, null)) return 0;

//Get hash code for the Name field if it is not null.
int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();

//Get hash code for the Code field.
int hashProductCode = product.Code.GetHashCode();

//Calculate the hash code for the product.
return hashProductName ^ hashProductCode;
}
}

Product[] store10 = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 } };

Product[] store20 = { new Product { Name = "apple", Code = 9 },
new Product { Name = "lemon", Code = 12 } };

//Get the products from the both arrays
//excluding duplicates.

IEnumerable<Product> union =
store10.Union(store20, new ProductComparer());

foreach (Product product in union)
Console.WriteLine(product.Name + " " + product.Code);

/*
This code produces the following output:

apple 9
orange 4
lemon 12
*/

Where

基于谓词筛选值序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
List<string> fruits =
new List<string> { "apple", "passionfruit", "banana", "mango",
"orange", "blueberry", "grape", "strawberry" };

IEnumerable<string> query = fruits.Where(fruit => fruit.Length < 6);

foreach (string fruit in query)
{
Console.WriteLine(fruit);
}
/*
This code produces the following output:

apple
mango
grape
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int[] numbers = { 0, 30, 20, 15, 90, 85, 40, 75 };

IEnumerable<int> query =
numbers.Where((number, index) => number <= index * 10);

foreach (int number in query)
{
Console.WriteLine(number);
}
/*
This code produces the following output:

0
20
15
40
*/