C#的 LINQ 拓展方法

Posted by Zeusro on March 9, 2018
👈🏻 Select language
  1. 前期准备
    • 定义实体
    • 定义集合
  2. 完整代码
  3. 参考链接

前期准备

  • 定义实体

    public class Person
    {

        /// <summary>
        /// 身高
        /// </summary>
        /// <returns></returns>
        public int Height { get; set; }

        /// <summary>
        /// 高度
        /// </summary>
        /// <returns></returns>
        public int Weight { get; set; }

        /// <summary>
        /// 生日
        /// </summary>
        /// <returns></returns>
        public DateTime Birthday { get; set; }

        /// <summary>
        /// 爱好
        /// </summary>
        /// <returns></returns>
        public List<string> Hobbies { get; set; }

        /// <summary>
        /// 身份证号
        /// </summary>
        /// <returns></returns>
        public string Identifier { get; set; }

        /// <summary>
        /// 地址
        /// </summary>
        /// <returns></returns>
        public string Address { get; set; }

        public Sex Sex { get; set; }


    }

    /// <summary>
    /// 性别
    /// </summary>
    public enum Sex : short
    {
        //男
        Male = 1,
        //女
        Female,
        //第三性 https://zh.wikipedia.org/wiki/%E7%AC%AC%E4%B8%89%E6%80%A7
        X,

    }
  • 定义集合
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
 Person female = new Person()
            {
                Birthday = new DateTime(1981, 1, 1),
                Height = 165,
                Weight = 50,
                Sex = Sex.Female,
                Address = "北京",
                Identifier = "1",
                Hobbies = new List<string>() { "吃飯", "逛街" },
            };
            Person male = new Person()
            {
                Birthday = new DateTime(1982, 2, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "2",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            Person x = new Person()
            {
                Birthday = new DateTime(1983, 3, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.X,
                Address = "北京",
                Identifier = "3",
                Hobbies = new List<string>() { "吃飯", "上網" },
            };
            Person male2 = new Person()
            {
                Birthday = new DateTime(1984, 1, 1),
                Height = 150,
                Weight = 35,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "4",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            List<Person> list1 = new List<Person>() { female, male, x };
            List<Person> list2 = new List<Person>() { female, male2 };

完整代码

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
 class Program
    {
        static void Main(string[] args)
        {
            Person female = new Person()
            {
                Birthday = new DateTime(1981, 1, 1),
                Height = 165,
                Weight = 50,
                Sex = Sex.Female,
                Address = "北京",
                Identifier = "1",
                Hobbies = new List<string>() { "吃飯", "逛街" },
            };
            Person male = new Person()
            {
                Birthday = new DateTime(1982, 2, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "2",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            Person x = new Person()
            {
                Birthday = new DateTime(1983, 3, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.X,
                Address = "北京",
                Identifier = "3",
                Hobbies = new List<string>() { "吃飯", "上網" },
            };
            Person male2 = new Person()
            {
                Birthday = new DateTime(1984, 1, 1),
                Height = 150,
                Weight = 35,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "4",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            List<Person> list1 = new List<Person>() { female, male, x };
            List<Person> list2 = new List<Person>() { female, male2 };
            int count1 = list1.Where(o => o.Birthday.Equals(new DateTime(1990, 1, 1)) && o.Sex == Sex.Male).Count();
            long count2 = list1.Where(o => o.Birthday.Equals(new DateTime(1990, 1, 1)) && o.Sex == Sex.Male).LongCount();
            /*              
             0
             0
             */
            var group1 = list1.GroupBy(o => o.Sex);
            //当我们使用 GroupBy() 扩展方法时,使用了延迟执行。 这意味着,当你遍历集合的时候,下一个要出现的项目可能会或者可能不会被加载。 这是一个很大的性能改进,但它会引起有趣的副作用。
            list1.RemoveAll(o => o.Sex == Sex.X);//定义 groupby 集合后对原集合进行修改,会发现group1里面已经没了 Sex=X的分组
            foreach (var groupByItem in group1)
            {
                Sex sex = groupByItem.Key;
                System.Console.WriteLine(sex);
                foreach (Person person in groupByItem)
                {                    
                    System.Console.WriteLine(JsonConvert.SerializeObject(person));
                }
            }
            /*
            输出结果:
            {"Height":165,"Weight":50,"Birthday":"1981-01-01T00:00:00","Hobbies":["吃飯","逛街"],"Identifier":"1","Address":"北京","Sex":2}
            Male
            {"Height":170,"Weight":50,"Birthday":"1982-02-01T00:00:00","Hobbies":["吃飯","看電影"],"Identifier":"2","Address":"北京","Sex":1}
            Female
            {"Height":165,"Weight":50,"Birthday":"1981-01-01T00:00:00","Hobbies":["吃飯","逛街"],"Identifier":"1","Address":"北京","Sex":2}
            Male
            {"Height":170,"Weight":50,"Birthday":"1982-02-01T00:00:00","Hobbies":["吃飯","看電影"],"Identifier":"2","Address":"北京","Sex":1}
             */
            //该 ToLookup() 方法创建一个类似 字典(Dictionary ) 的列表List, 但是它是一个新的 .NET Collection 叫做 lookup。 Lookup,不像Dictionary, 是不可改变的。 这意味着一旦你创建一个lookup, 你不能添加或删除元素。
            var group2 = list1.ToLookup(o => o.Sex);
            foreach (var groupByItem in group2)
            {
                Sex sex = groupByItem.Key;
                foreach (Person person in groupByItem)
                {
                    System.Console.WriteLine(sex);
                    System.Console.WriteLine(JsonConvert.SerializeObject(person));
                }

            }
            /*
            输出结果:            
            {"Height":165,"Weight":50,"Birthday":"1981-01-01T00:00:00","Hobbies":["吃飯","逛街"],"Identifier":"1","Address":"北京","Sex":3}
            {"Height":170,"Weight":50,"Birthday":"1982-02-01T00:00:00","Hobbies":["吃飯","看電影"],"Identifier":"2","Address":"北京","Sex":3}
             */
            var after90 = list1.Where(o => o.Birthday >= new DateTime(1990, 1, 1)).First();//如果结果为空,将会导致异常,所以一般极少使用该方法
            //An unhandled exception of type 'System.InvalidOperationException' occurred in System.Linq.dll: 'Sequence contains no elements'
            after90 = list1.Where(o => o.Birthday >= new DateTime(1990, 1, 1)).FirstOrDefault();
            var after00 = list1.Where(o => o.Birthday >= new DateTime(2000, 1, 1)).FirstOrDefault();
            list1.ForEach(item =>
            {
                //在ForEach當中可對集合進行操作
                item.Sex = Sex.X;
            });
            list1.ForEach(item =>
           {
               System.Console.WriteLine(JsonConvert.SerializeObject(item));
           });
            int maxHeight = list1.Select(o => o.Height).Max();
            //同 list1.Max(o => o.Height);
            int minWeight = list1.Min(o => o.Weight);            
            list1.Select(o=>o.Identifier).Distinct();
            list1.Skip(1).Take(2);
            //升序
            list1 = list1.OrderBy(o => o.Birthday).ToList();
            //降序
            list1 = list1.OrderByDescending(o => o.Birthday).ToList();
            //连接,下面表示把 list1和 list2当中相同身份证号的取出来,生成一个新的集合            
            //实际上, join 有另外的用法,类似 sqlserver 里面的多表连接,将不同数据源结合到一起,生成新的数据结构
            var intersect = list1.Join(list2, o => o.Identifier, o => o.Identifier, (a, b) => a).ToList();
            //交集 list1 ∩ list2                        
            intersect = list1.Intersect(list2).ToList();
            //并集list1 ∪ list2 
            var union = list1.Union(list2).ToList();
            //差集list1 - list2
            var except = list1.Except(list2).ToList();
            //数据结构转换
            list1.ToArray();
            //注意如果 key 重复,ToDictionary会导致出错
            list1.ToDictionary(o => o.Identifier, o => o);
            list1.ToHashSet();
        }
    }

参考链接:

  1. 语言集成查询 (LINQ)
  2. LINQ操作数组(交集,并集,差集,最值,平均,去重复)
  3. C# 中奇妙的函数 – 1. ToLookup
  1. Preparation
    • Define Entity
    • Define Collection
  2. Complete Code
  3. Reference Links

Preparation

  • Define Entity

    public class Person
    {

        /// <summary>
        /// Height
        /// </summary>
        /// <returns></returns>
        public int Height { get; set; }

        /// <summary>
        /// Weight
        /// </summary>
        /// <returns></returns>
        public int Weight { get; set; }

        /// <summary>
        /// Birthday
        /// </summary>
        /// <returns></returns>
        public DateTime Birthday { get; set; }

        /// <summary>
        /// Hobbies
        /// </summary>
        /// <returns></returns>
        public List<string> Hobbies { get; set; }

        /// <summary>
        /// ID Number
        /// </summary>
        /// <returns></returns>
        public string Identifier { get; set; }

        /// <summary>
        /// Address
        /// </summary>
        /// <returns></returns>
        public string Address { get; set; }

        public Sex Sex { get; set; }


    }

    /// <summary>
    /// Gender
    /// </summary>
    public enum Sex : short
    {
        //Male
        Male = 1,
        //Female
        Female,
        //Third Gender https://zh.wikipedia.org/wiki/%E7%AC%AC%E4%B8%89%E6%80%A7
        X,

    }
  • Define 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 Person female = new Person()
            {
                Birthday = new DateTime(1981, 1, 1),
                Height = 165,
                Weight = 50,
                Sex = Sex.Female,
                Address = "北京",
                Identifier = "1",
                Hobbies = new List<string>() { "吃飯", "逛街" },
            };
            Person male = new Person()
            {
                Birthday = new DateTime(1982, 2, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "2",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            Person x = new Person()
            {
                Birthday = new DateTime(1983, 3, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.X,
                Address = "北京",
                Identifier = "3",
                Hobbies = new List<string>() { "吃飯", "上網" },
            };
            Person male2 = new Person()
            {
                Birthday = new DateTime(1984, 1, 1),
                Height = 150,
                Weight = 35,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "4",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            List<Person> list1 = new List<Person>() { female, male, x };
            List<Person> list2 = new List<Person>() { female, male2 };

Complete Code

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
 class Program
    {
        static void Main(string[] args)
        {
            Person female = new Person()
            {
                Birthday = new DateTime(1981, 1, 1),
                Height = 165,
                Weight = 50,
                Sex = Sex.Female,
                Address = "北京",
                Identifier = "1",
                Hobbies = new List<string>() { "吃飯", "逛街" },
            };
            Person male = new Person()
            {
                Birthday = new DateTime(1982, 2, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "2",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            Person x = new Person()
            {
                Birthday = new DateTime(1983, 3, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.X,
                Address = "北京",
                Identifier = "3",
                Hobbies = new List<string>() { "吃飯", "上網" },
            };
            Person male2 = new Person()
            {
                Birthday = new DateTime(1984, 1, 1),
                Height = 150,
                Weight = 35,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "4",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            List<Person> list1 = new List<Person>() { female, male, x };
            List<Person> list2 = new List<Person>() { female, male2 };
            int count1 = list1.Where(o => o.Birthday.Equals(new DateTime(1990, 1, 1)) && o.Sex == Sex.Male).Count();
            long count2 = list1.Where(o => o.Birthday.Equals(new DateTime(1990, 1, 1)) && o.Sex == Sex.Male).LongCount();
            /*              
             0
             0
             */
            var group1 = list1.GroupBy(o => o.Sex);
            //When we use the GroupBy() extension method, deferred execution is used. This means that when you iterate through the collection, the next item to appear may or may not be loaded. This is a big performance improvement, but it can cause interesting side effects.
            list1.RemoveAll(o => o.Sex == Sex.X);//After defining the groupby collection, modifying the original collection will find that the Sex=X group is already gone from group1
            foreach (var groupByItem in group1)
            {
                Sex sex = groupByItem.Key;
                System.Console.WriteLine(sex);
                foreach (Person person in groupByItem)
                {                    
                    System.Console.WriteLine(JsonConvert.SerializeObject(person));
                }
            }
            /*
            Output:
            {"Height":165,"Weight":50,"Birthday":"1981-01-01T00:00:00","Hobbies":["吃飯","逛街"],"Identifier":"1","Address":"北京","Sex":2}
            Male
            {"Height":170,"Weight":50,"Birthday":"1982-02-01T00:00:00","Hobbies":["吃飯","看電影"],"Identifier":"2","Address":"北京","Sex":1}
            Female
            {"Height":165,"Weight":50,"Birthday":"1981-01-01T00:00:00","Hobbies":["吃飯","逛街"],"Identifier":"1","Address":"北京","Sex":2}
            Male
            {"Height":170,"Weight":50,"Birthday":"1982-02-01T00:00:00","Hobbies":["吃飯","看電影"],"Identifier":"2","Address":"北京","Sex":1}
             */
            //The ToLookup() method creates a Dictionary-like List, but it's a new .NET Collection called lookup. Lookup, unlike Dictionary, is immutable. This means once you create a lookup, you cannot add or remove elements.
            var group2 = list1.ToLookup(o => o.Sex);
            foreach (var groupByItem in group2)
            {
                Sex sex = groupByItem.Key;
                foreach (Person person in groupByItem)
                {
                    System.Console.WriteLine(sex);
                    System.Console.WriteLine(JsonConvert.SerializeObject(person));
                }

            }
            /*
            Output:            
            {"Height":165,"Weight":50,"Birthday":"1981-01-01T00:00:00","Hobbies":["吃飯","逛街"],"Identifier":"1","Address":"北京","Sex":3}
            {"Height":170,"Weight":50,"Birthday":"1982-02-01T00:00:00","Hobbies":["吃飯","看電影"],"Identifier":"2","Address":"北京","Sex":3}
             */
            var after90 = list1.Where(o => o.Birthday >= new DateTime(1990, 1, 1)).First();//If the result is empty, it will cause an exception, so this method is rarely used
            //An unhandled exception of type 'System.InvalidOperationException' occurred in System.Linq.dll: 'Sequence contains no elements'
            after90 = list1.Where(o => o.Birthday >= new DateTime(1990, 1, 1)).FirstOrDefault();
            var after00 = list1.Where(o => o.Birthday >= new DateTime(2000, 1, 1)).FirstOrDefault();
            list1.ForEach(item =>
            {
                //Can operate on the collection within ForEach
                item.Sex = Sex.X;
            });
            list1.ForEach(item =>
           {
               System.Console.WriteLine(JsonConvert.SerializeObject(item));
           });
            int maxHeight = list1.Select(o => o.Height).Max();
            //Same as list1.Max(o => o.Height);
            int minWeight = list1.Min(o => o.Weight);            
            list1.Select(o=>o.Identifier).Distinct();
            list1.Skip(1).Take(2);
            //Ascending
            list1 = list1.OrderBy(o => o.Birthday).ToList();
            //Descending
            list1 = list1.OrderByDescending(o => o.Birthday).ToList();
            //Join, below means take out items with the same ID number from list1 and list2, generate a new collection            
            //Actually, join has other uses, similar to multi-table joins in sqlserver, combining different data sources together to generate new data structures
            var intersect = list1.Join(list2, o => o.Identifier, o => o.Identifier, (a, b) => a).ToList();
            //Intersection list1 ∩ list2                        
            intersect = list1.Intersect(list2).ToList();
            //Union list1 ∪ list2 
            var union = list1.Union(list2).ToList();
            //Difference list1 - list2
            var except = list1.Except(list2).ToList();
            //Data Structure Conversion
            list1.ToArray();
            //Note if key is duplicate, ToDictionary will cause an error
            list1.ToDictionary(o => o.Identifier, o => o);
            list1.ToHashSet();
        }
    }
  1. Language Integrated Query (LINQ)
  2. LINQ Operations on Arrays (Intersection, Union, Difference, Max, Min, Average, Remove Duplicates)
  3. Wonderful Functions in C# – 1. ToLookup
  1. Подготовка
    • Определение сущности
    • Определение коллекции
  2. Полный код
  3. Ссылки

Подготовка

  • Определение сущности

    public class Person
    {

        /// <summary>
        /// Рост
        /// </summary>
        /// <returns></returns>
        public int Height { get; set; }

        /// <summary>
        /// Вес
        /// </summary>
        /// <returns></returns>
        public int Weight { get; set; }

        /// <summary>
        /// День рождения
        /// </summary>
        /// <returns></returns>
        public DateTime Birthday { get; set; }

        /// <summary>
        /// Хобби
        /// </summary>
        /// <returns></returns>
        public List<string> Hobbies { get; set; }

        /// <summary>
        /// Номер удостоверения личности
        /// </summary>
        /// <returns></returns>
        public string Identifier { get; set; }

        /// <summary>
        /// Адрес
        /// </summary>
        /// <returns></returns>
        public string Address { get; set; }

        public Sex Sex { get; set; }


    }

    /// <summary>
    /// Пол
    /// </summary>
    public enum Sex : short
    {
        //Мужской
        Male = 1,
        //Женский
        Female,
        //Третий пол https://zh.wikipedia.org/wiki/%E7%AC%AC%E4%B8%89%E6%80%A7
        X,

    }
  • Определение коллекции
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
 Person female = new Person()
            {
                Birthday = new DateTime(1981, 1, 1),
                Height = 165,
                Weight = 50,
                Sex = Sex.Female,
                Address = "北京",
                Identifier = "1",
                Hobbies = new List<string>() { "吃飯", "逛街" },
            };
            Person male = new Person()
            {
                Birthday = new DateTime(1982, 2, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "2",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            Person x = new Person()
            {
                Birthday = new DateTime(1983, 3, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.X,
                Address = "北京",
                Identifier = "3",
                Hobbies = new List<string>() { "吃飯", "上網" },
            };
            Person male2 = new Person()
            {
                Birthday = new DateTime(1984, 1, 1),
                Height = 150,
                Weight = 35,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "4",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            List<Person> list1 = new List<Person>() { female, male, x };
            List<Person> list2 = new List<Person>() { female, male2 };

Полный код

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
 class Program
    {
        static void Main(string[] args)
        {
            Person female = new Person()
            {
                Birthday = new DateTime(1981, 1, 1),
                Height = 165,
                Weight = 50,
                Sex = Sex.Female,
                Address = "北京",
                Identifier = "1",
                Hobbies = new List<string>() { "吃飯", "逛街" },
            };
            Person male = new Person()
            {
                Birthday = new DateTime(1982, 2, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "2",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            Person x = new Person()
            {
                Birthday = new DateTime(1983, 3, 1),
                Height = 170,
                Weight = 50,
                Sex = Sex.X,
                Address = "北京",
                Identifier = "3",
                Hobbies = new List<string>() { "吃飯", "上網" },
            };
            Person male2 = new Person()
            {
                Birthday = new DateTime(1984, 1, 1),
                Height = 150,
                Weight = 35,
                Sex = Sex.Male,
                Address = "北京",
                Identifier = "4",
                Hobbies = new List<string>() { "吃飯", "看電影" },
            };
            List<Person> list1 = new List<Person>() { female, male, x };
            List<Person> list2 = new List<Person>() { female, male2 };
            int count1 = list1.Where(o => o.Birthday.Equals(new DateTime(1990, 1, 1)) && o.Sex == Sex.Male).Count();
            long count2 = list1.Where(o => o.Birthday.Equals(new DateTime(1990, 1, 1)) && o.Sex == Sex.Male).LongCount();
            /*              
             0
             0
             */
            var group1 = list1.GroupBy(o => o.Sex);
            //Когда мы используем метод расширения GroupBy(), используется отложенное выполнение. Это означает, что при итерации по коллекции следующий элемент может быть или не быть загружен. Это большое улучшение производительности, но может вызвать интересные побочные эффекты.
            list1.RemoveAll(o => o.Sex == Sex.X);//После определения коллекции groupby, изменение исходной коллекции обнаружит, что группа Sex=X уже отсутствует в group1
            foreach (var groupByItem in group1)
            {
                Sex sex = groupByItem.Key;
                System.Console.WriteLine(sex);
                foreach (Person person in groupByItem)
                {                    
                    System.Console.WriteLine(JsonConvert.SerializeObject(person));
                }
            }
            /*
            Вывод:
            {"Height":165,"Weight":50,"Birthday":"1981-01-01T00:00:00","Hobbies":["吃飯","逛街"],"Identifier":"1","Address":"北京","Sex":2}
            Male
            {"Height":170,"Weight":50,"Birthday":"1982-02-01T00:00:00","Hobbies":["吃飯","看電影"],"Identifier":"2","Address":"北京","Sex":1}
            Female
            {"Height":165,"Weight":50,"Birthday":"1981-01-01T00:00:00","Hobbies":["吃飯","逛街"],"Identifier":"1","Address":"北京","Sex":2}
            Male
            {"Height":170,"Weight":50,"Birthday":"1982-02-01T00:00:00","Hobbies":["吃飯","看電影"],"Identifier":"2","Address":"北京","Sex":1}
             */
            //Метод ToLookup() создает список, похожий на Dictionary, но это новая коллекция .NET под названием lookup. Lookup, в отличие от Dictionary, неизменяем. Это означает, что после создания lookup вы не можете добавлять или удалять элементы.
            var group2 = list1.ToLookup(o => o.Sex);
            foreach (var groupByItem in group2)
            {
                Sex sex = groupByItem.Key;
                foreach (Person person in groupByItem)
                {
                    System.Console.WriteLine(sex);
                    System.Console.WriteLine(JsonConvert.SerializeObject(person));
                }

            }
            /*
            Вывод:            
            {"Height":165,"Weight":50,"Birthday":"1981-01-01T00:00:00","Hobbies":["吃飯","逛街"],"Identifier":"1","Address":"北京","Sex":3}
            {"Height":170,"Weight":50,"Birthday":"1982-02-01T00:00:00","Hobbies":["吃飯","看電影"],"Identifier":"2","Address":"北京","Sex":3}
             */
            var after90 = list1.Where(o => o.Birthday >= new DateTime(1990, 1, 1)).First();//Если результат пуст, это вызовет исключение, поэтому этот метод редко используется
            //An unhandled exception of type 'System.InvalidOperationException' occurred in System.Linq.dll: 'Sequence contains no elements'
            after90 = list1.Where(o => o.Birthday >= new DateTime(1990, 1, 1)).FirstOrDefault();
            var after00 = list1.Where(o => o.Birthday >= new DateTime(2000, 1, 1)).FirstOrDefault();
            list1.ForEach(item =>
            {
                //Можно работать с коллекцией внутри ForEach
                item.Sex = Sex.X;
            });
            list1.ForEach(item =>
           {
               System.Console.WriteLine(JsonConvert.SerializeObject(item));
           });
            int maxHeight = list1.Select(o => o.Height).Max();
            //То же, что list1.Max(o => o.Height);
            int minWeight = list1.Min(o => o.Weight);            
            list1.Select(o=>o.Identifier).Distinct();
            list1.Skip(1).Take(2);
            //По возрастанию
            list1 = list1.OrderBy(o => o.Birthday).ToList();
            //По убыванию
            list1 = list1.OrderByDescending(o => o.Birthday).ToList();
            //Соединение, ниже означает извлечение элементов с одинаковым номером ID из list1 и list2, создание новой коллекции            
            //На самом деле, join имеет другое использование, подобное многотабличным соединениям в sqlserver, объединяя разные источники данных вместе для создания новых структур данных
            var intersect = list1.Join(list2, o => o.Identifier, o => o.Identifier, (a, b) => a).ToList();
            //Пересечение list1 ∩ list2                        
            intersect = list1.Intersect(list2).ToList();
            //Объединение list1 ∪ list2 
            var union = list1.Union(list2).ToList();
            //Разность list1 - list2
            var except = list1.Except(list2).ToList();
            //Преобразование структуры данных
            list1.ToArray();
            //Обратите внимание, если ключ дублируется, ToDictionary вызовет ошибку
            list1.ToDictionary(o => o.Identifier, o => o);
            list1.ToHashSet();
        }
    }

Ссылки:

  1. Язык интегрированных запросов (LINQ)
  2. Операции LINQ с массивами (пересечение, объединение, разность, максимум, минимум, среднее, удаление дубликатов)
  3. Удивительные функции в C# – 1. ToLookup