From ee3f628442c9efc7ec3df19c44742ed88eb69302 Mon Sep 17 00:00:00 2001 From: bicijinlian Date: Sat, 7 Sep 2019 14:29:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=83=E7=B4=A0=E6=93=8D=E4=BD=9C=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LinqStudy.Test/ExpressionTree/表达式树.md | 1 + LinqStudy.Test/LinqStudy.Test.csproj | 4 - LinqStudy.Test/LinqToObject/ElementTest.cs | 109 +++++++ LinqStudy.Test/LinqToObject/QuantifierTest.cs | 307 ++++++++++++++++++ .../LinqToObject/SequenceEqualTest.cs | 64 +--- .../LinqToObject/TypeConvertTest.cs | 20 -- LinqStudy.Test/LinqToObject/WhereTest.cs | 10 +- .../LinqToObject/标准查询操作符.md | 35 ++ LinqStudy/Class1.cs | 8 - LinqStudy/Models/Person.cs | 3 + LinqStudy/Models/PersonEqual.cs | 2 +- LinqStudy/Models/PersonEqualId.cs | 28 ++ LinqStudy/Models/StudentOverriteEquals.cs | 34 ++ 13 files changed, 533 insertions(+), 92 deletions(-) create mode 100644 LinqStudy.Test/ExpressionTree/表达式树.md create mode 100644 LinqStudy.Test/LinqToObject/QuantifierTest.cs create mode 100644 LinqStudy.Test/LinqToObject/标准查询操作符.md delete mode 100644 LinqStudy/Class1.cs create mode 100644 LinqStudy/Models/PersonEqualId.cs create mode 100644 LinqStudy/Models/StudentOverriteEquals.cs diff --git a/LinqStudy.Test/ExpressionTree/表达式树.md b/LinqStudy.Test/ExpressionTree/表达式树.md new file mode 100644 index 0000000..bad650c --- /dev/null +++ b/LinqStudy.Test/ExpressionTree/表达式树.md @@ -0,0 +1 @@ +# 表达式树 \ No newline at end of file diff --git a/LinqStudy.Test/LinqStudy.Test.csproj b/LinqStudy.Test/LinqStudy.Test.csproj index 86d69ce..b4c1c42 100644 --- a/LinqStudy.Test/LinqStudy.Test.csproj +++ b/LinqStudy.Test/LinqStudy.Test.csproj @@ -18,10 +18,6 @@ - - - - diff --git a/LinqStudy.Test/LinqToObject/ElementTest.cs b/LinqStudy.Test/LinqToObject/ElementTest.cs index 3918a6a..0e1e697 100644 --- a/LinqStudy.Test/LinqToObject/ElementTest.cs +++ b/LinqStudy.Test/LinqToObject/ElementTest.cs @@ -451,5 +451,114 @@ namespace LinqStudy.Test.LinqToObject Assert.Throws(singleOrDefalutAction); } #endregion + + #region ElementAt + + /// + /// ElementAt:返回集合中给定索引(索引从0开始)处的元素,延迟执行。 + /// + [Fact] + public void ElementAt_Test() + { + List peoples = new List() + { + new Person(){ Id=1, Name="wanggaofeng", Age=33}, + new Person(){ Id=2, Name="lishi", Age=32}, + new Person(){ Id=3, Name="wangwu", Age=44}, + }; + + var queryItem = peoples.ElementAt(0); + var queryItemName = queryItem.Name; + + Assert.Equal("wanggaofeng", queryItemName); + } + + /// + /// ArgumentNullException异常:数据源为Null时,引发。 + /// + [Fact] + public void ElementAt_ArgumentNullException_Test() + { + List peoples = null; + + Action queryAction = () => peoples.ElementAt(0); + + Assert.Throws(queryAction); + } + + /// + /// ArgumentOutOfRangeException异常:指定索引超出序列范围时,引发。 + /// + [Fact] + public void ElementAt_ArgumentOutOfRangeException_Test() + { + List peoples = new List() + { + new Person(){ Id=1, Name="wanggaofeng", Age=33}, + new Person(){ Id=2, Name="lishi", Age=32}, + new Person(){ Id=3, Name="wangwu", Age=44}, + }; + + Action queryAction = () => peoples.ElementAt(100); + + Assert.Throws(queryAction); + } + #endregion + + #region ElementAtOrDefault + /// + /// ElementAtOrDefault:获取指定索引处的元素或如果超出索引范围时返回默认项;延迟执行。 + /// + [Fact] + public void ElementAtOrDefault_ElementAt() + { + List peoples = new List() + { + new Person(){ Id=1, Name="wanggaofeng", Age=33} + }; + + var queryItem = peoples.ElementAtOrDefault(0); + var queryItemName = queryItem.Name; + + Assert.Equal("wanggaofeng", queryItemName); + } + + /// + /// 超出索引范围,返回默认项。 + /// 注意:引用和可空类型,返回null + /// + [Fact] + public void ElementAtOrDefault_Default() + { + List peoples = new List() { }; + + var queryItem = peoples.ElementAtOrDefault(2); + + Assert.Null(queryItem); + } + + [Fact] + public void ElementAtOrDefault_ArgumentNullException() + { + List peoples = null; + + Action queryAction = () => peoples.ElementAtOrDefault(0); + + Assert.Throws(queryAction); + } + + /// + /// 查询不到数据,不异常 + /// + [Fact] + public void ElementAtOrDefault_QueryEmpty_NoArgumentNullException() + { + List peoples = new List(); + + var queryItme = peoples.ElementAtOrDefault(5); + + Assert.Null(queryItme); + } + #endregion } } diff --git a/LinqStudy.Test/LinqToObject/QuantifierTest.cs b/LinqStudy.Test/LinqToObject/QuantifierTest.cs new file mode 100644 index 0000000..0d13c7b --- /dev/null +++ b/LinqStudy.Test/LinqToObject/QuantifierTest.cs @@ -0,0 +1,307 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Linq; + +using Xunit; +using FluentAssertions; + + +namespace LinqStudy.Test.LinqToObject +{ + /// + /// 量词操作符 + /// + public class QuantifierTest + { + #region Any + + /// + /// Andy:序列中是否存在任一满足条件的项;为加快判断速度,立即执行 + /// + [Fact] + public void Any_Test() + { + List peoples = new List() + { + new Person(){ Id = 1, Name = "王小明",Age = 10 }, + new Person(){ Id = 2, Name = "西站热",Age = 66 }, + new Person(){ Id = 3, Name = "西门吹雪",Age = 45 }, + }; + + var anyQuery = peoples.Any(q => q.Name.StartsWith("西")); + + Assert.True(anyQuery); + } + + /// + /// 立即执行 + /// + [Fact] + public void Any_Immediately_Test() + { + List peoples = new List() + { + new Person(){ Id = 1, Name = "王小明",Age = 10 }, + new Person(){ Id = 2, Name = "东方不败",Age = 66 }, + new Person(){ Id = 3, Name = "西门吹雪",Age = 45 }, + }; + + //查询 + var anyQuery = peoples.Any(q => q.Id >= 4); + + //查询后添加满足条件的项 + peoples.Add(new Person { Id = 5, Name = "小东", Age = 44 }); + + //结果 + var delayResult = anyQuery; + //断言 + Assert.False(delayResult); + } + + /// + /// 重载方法:查询表达式 + /// + [Fact] + public void Any_Overload_Test() + { + List peoples = new List() + { + new Person(){ Id = 1, Name = "王小明",Age = 10 }, + new Person(){ Id = 2, Name = "东方不败",Age = 66 }, + new Person(){ Id = 3, Name = "西门吹雪",Age = 45 }, + }; + + var anyQuery = peoples.Any(q => q.Id >= 2); + + Assert.True(anyQuery); + } + + /// + /// ArgumentNullException异常 + /// + [Fact] + public void Any_ArgumentNullException_Test() + { + List peoples =null; + + Action anyQueryAction =() => peoples.Any(q => q.Id >= 2); + + Assert.Throws(anyQueryAction); + } + #endregion + + #region All + + /// + /// All:序列中是否所有项都满足条件; + /// 立即执行 + /// + [Fact] + public void All_Test() + { + List peoples = new List() + { + new Person(){ Id = 1, Name = "王小明",Age = 10 }, + new Person(){ Id = 2, Name = "王小庆",Age = 66 }, + new Person(){ Id = 3, Name = "西门之王",Age = 45 }, + }; + + var anyQuery = peoples.All(q => q.Name.Contains("王")); + + Assert.True(anyQuery); + } + + /// + /// 立即执行 + /// + [Fact] + public void All_Immediately_Test() + { + List peoples = new List() + { + new Person(){ Id = 1, Name = "王小明",Age = 10 }, + new Person(){ Id = 2, Name = "王小庆",Age = 66 }, + new Person(){ Id = 3, Name = "西门",Age = 45 }, + }; + + //查询 + var anyQuery = peoples.All(q => q.Id >= 4); + + //查询后设置满足条件的项 + peoples[2].Name += "之王"; + + //结果 + var delayResult = anyQuery; + + //断言 + Assert.False(delayResult); + } + + /// + /// 重载方法:查询表达式 + /// + [Fact] + public void All_Overload_Test() + { + List peoples = new List() + { + new Person(){ Id = 1, Name = "王小明",Age = 10 }, + new Person(){ Id = 2, Name = "东方不败",Age = 66 }, + new Person(){ Id = 3, Name = "西门吹雪",Age = 45 }, + }; + + var anyQuery = peoples.All(q => q.Name.Length >= 2); + + Assert.True(anyQuery); + } + + /// + /// ArgumentNullException异常 + /// + [Fact] + public void All_ArgumentNullException_Test() + { + List peoples = null; + + Action anyQueryAction = () => peoples.All(q => q.Id >= 2); + + Assert.Throws(anyQueryAction); + } + #endregion + + #region Contains + + /// + /// Contains:序列中是否包含指定的项; + /// 立即执行 + /// + [Fact] + public void Contains_Test() + { + List arr = new List() {1,2,3,4,5 }; + + var anyQuery = arr.Contains(2); + + Assert.True(anyQuery); + } + + /// + /// 不包含时,返回false + /// + [Fact] + public void Contains_No_Test() + { + List arr = new List() { 1, 2, 3, 4, 5 }; + + var anyQuery = arr.Contains(100); + + Assert.False(anyQuery); + } + + /// + /// 引用类型的包含,指引用的对象是同一个对象。 + /// 属性值全部相等,但引用地址不同,则不包含。 + /// + [Fact] + public void Contains_Reference_No_Test() + { + List peoples = new List() + { + new Person(){ Id = 1, Name = "王小明",Age = 10 }, + new Person(){ Id = 2, Name = "王小庆",Age = 66 }, + new Person(){ Id = 3, Name = "西门之王",Age = 45 }, + }; + + var current = new Person() { Id = 1, Name = "王小明", Age = 10 }; + var anyQuery = peoples.Contains(current); + + Assert.False(anyQuery); + } + + /// + /// 引用类型,包含:引用地址相同。 + /// + [Fact] + public void Contains_Reference_Yes_Test() + { + List peoples = new List() + { + new Person(){ Id = 1, Name = "王小明",Age = 10 }, + new Person(){ Id = 2, Name = "王小庆",Age = 66 }, + new Person(){ Id = 3, Name = "西门之王",Age = 45 }, + }; + + var queryItem = peoples.First(); + var isContain = peoples.Contains(queryItem); + + Assert.True(isContain); + } + + /// + /// 立即执行 + /// + [Fact] + public void Contains_Immediately_Test() + { + List peoples = new List() + { + new Person(){ Id = 1, Name = "王小明",Age = 10 }, + new Person(){ Id = 2, Name = "王小庆",Age = 66 }, + new Person(){ Id = 3, Name = "西门",Age = 45 }, + }; + + var addItem = new Person() { Id = 4, Name = "张三", Age = 33 }; + + //不包含指定项 + var containQuery = peoples.Contains(addItem); + + //操作后,添加到集合,此时应该包含 + peoples.Add(addItem); + + //断言:不包含 + //因为添加前,已经立即执行,保留结果;后面再添加项,不影响以前的执行结果。 + Assert.False(containQuery); + } + + /// + /// 重载方法:使用自定义比较器 + /// 虽然大部分属性都不一样,但是比较器认为Id属性相同即相等,Contains就认为包含。 + /// + [Fact] + public void Contains_Overload_Test() + { + List peoples = new List() + { + new Person(){ Id = 1, Name = "王小明",Age = 10 }, + new Person(){ Id = 2, Name = "东方不败",Age = 66 }, + new Person(){ Id = 3, Name = "西门吹雪",Age = 45 }, + }; + + var people = new Person() { Id = 3, Name = "小清闲", Age = 88 }; + + //自定义比较器:Id相同即为同一个对象 + PersonEqualId equalId = new PersonEqualId(); + var anyQuery = peoples.Contains(people, new PersonEqualId()); + + //比较器相等,即包含 + Assert.True(anyQuery); + } + + /// + /// NullReferenceException 异常 + /// + [Fact] + public void Contains_NullReferenceException_Test() + { + List peoples = null; + + var people = new Person() { Id = 3, Name = "小清闲", Age = 88 }; + + Action anyQueryAction = () => peoples.Contains(people); + + Assert.Throws(anyQueryAction); + } + #endregion + } +} diff --git a/LinqStudy.Test/LinqToObject/SequenceEqualTest.cs b/LinqStudy.Test/LinqToObject/SequenceEqualTest.cs index 981c1ea..49c318a 100644 --- a/LinqStudy.Test/LinqToObject/SequenceEqualTest.cs +++ b/LinqStudy.Test/LinqToObject/SequenceEqualTest.cs @@ -159,16 +159,16 @@ namespace LinqStudy.Test.LinqToObject [Fact] public void SequenceEqual_OverrideEquals_Test() { - List sequence1 = new List() + List sequence1 = new List() { - new Student(){Id=1,Name="张三",Age=20}, - new Student(){Id=1,Name="李四",Age=20}, + new StudentOverriteEquals(){Id=1,Name="张三",Age=20}, + new StudentOverriteEquals(){Id=1,Name="李四",Age=20}, }; - List sequence2 = new List() + List sequence2 = new List() { - new Student(){Id=1,Name="李四",Age=20}, - new Student(){Id=1,Name="张三",Age=20}, + new StudentOverriteEquals(){Id=1,Name="李四",Age=20}, + new StudentOverriteEquals(){Id=1,Name="张三",Age=20}, }; Assert.True(sequence1.SequenceEqual(sequence2)); @@ -178,7 +178,7 @@ namespace LinqStudy.Test.LinqToObject /// 提供自定义比较器 /// [Fact] - public void Test() + public void SequenceEqual_CustomEqual_Test() { List sequence1 = new List() { @@ -194,55 +194,5 @@ namespace LinqStudy.Test.LinqToObject Assert.True(sequence1.SequenceEqual(sequence2, new PersonEqual())); } - - /// - /// 自定义Person比较器 - /// Id相同,则表示同一个对象 - /// - private class PersonEqual : IEqualityComparer - { - bool IEqualityComparer.Equals(Person x, Person y) - { - if (x==null || y==null) - { - return false; - } - - return x.Id == y.Id; - } - - int IEqualityComparer.GetHashCode(Person obj) - { - return obj.Id.GetHashCode(); - } - } - - /// - /// 重写比较方法 - /// - private class Student - { - public int Id { get; set; } - - public string Name { get; set; } - - public int Age { get; set; } - - public override bool Equals(object obj) - { - var other = obj as Student; - if (other == null) - { - return false; - } - - return Id==other.Id; - } - - public override int GetHashCode() - { - return this.Id.GetHashCode(); - } - } } } diff --git a/LinqStudy.Test/LinqToObject/TypeConvertTest.cs b/LinqStudy.Test/LinqToObject/TypeConvertTest.cs index 8cd6c0b..51f0e9b 100644 --- a/LinqStudy.Test/LinqToObject/TypeConvertTest.cs +++ b/LinqStudy.Test/LinqToObject/TypeConvertTest.cs @@ -375,26 +375,6 @@ namespace LinqStudy.Test.LinqToObject return dt; } - private Students GetStudents() - { - Students arrStudent = new Students - ( - new Student[] - { - new Student() { Name = "张三", Age = 23 }, - new Student() { Name = "李四", Age = 24 }, - new Student() { Name = "王五", Age = 45 }, - new Student() { Name = "DDD", Age = 21 }, - new Student() { Name = "BBB", Age = 14 }, - new Student() { Name = "CCC", Age = 3 }, - new Student() { Name = "AAA", Age = 22 }, - new Student() { Name = "BBB", Age = 55 }, - new Student() { Name = "CCC", Age = 43 }, - } - ); - - return arrStudent; - } #endregion } } diff --git a/LinqStudy.Test/LinqToObject/WhereTest.cs b/LinqStudy.Test/LinqToObject/WhereTest.cs index efed245..fc54e67 100644 --- a/LinqStudy.Test/LinqToObject/WhereTest.cs +++ b/LinqStudy.Test/LinqToObject/WhereTest.cs @@ -9,10 +9,13 @@ using Xunit; namespace LinqStudy.Test.LinqToObject { /// - /// where操作符:过滤查询条件 + /// where操作符 /// public class WhereTest { + /// + /// where:过滤查询条件 + /// [Fact] public void Where_Test() { @@ -28,8 +31,11 @@ namespace LinqStudy.Test.LinqToObject Assert.Equal(2, age); } + /// + /// ArgumentNullException 异常 + /// [Fact] - public void Where_Argm_Test() + public void Where_ArgumentNullException_Test() { List Persons = null; diff --git a/LinqStudy.Test/LinqToObject/标准查询操作符.md b/LinqStudy.Test/LinqToObject/标准查询操作符.md new file mode 100644 index 0000000..d8b9020 --- /dev/null +++ b/LinqStudy.Test/LinqToObject/标准查询操作符.md @@ -0,0 +1,35 @@ +# 标准查询操作符 + +## 投影操作符 + + Select + +### SelectMany + +## 限制操作符 + +### Where + +## 排序操作符 + +### OrderBy + +## 联接操作符 + +## 分组操作符 + +## 串联操作符 + +## 聚合操作符 + +## 生成操作符 + +## 转换操作符 + +## 元素操作符 + +## 相等操作符 + +## 量词操作符 + +## 分割操作符 \ No newline at end of file diff --git a/LinqStudy/Class1.cs b/LinqStudy/Class1.cs deleted file mode 100644 index d85860f..0000000 --- a/LinqStudy/Class1.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace LinqStudy -{ - public class Class1 - { - } -} diff --git a/LinqStudy/Models/Person.cs b/LinqStudy/Models/Person.cs index 29e01e4..da45934 100644 --- a/LinqStudy/Models/Person.cs +++ b/LinqStudy/Models/Person.cs @@ -2,6 +2,9 @@ using System; namespace LinqStudy { + /// + /// + /// public class Person { public int Id{get;set;} diff --git a/LinqStudy/Models/PersonEqual.cs b/LinqStudy/Models/PersonEqual.cs index 9930af9..86237d0 100644 --- a/LinqStudy/Models/PersonEqual.cs +++ b/LinqStudy/Models/PersonEqual.cs @@ -5,7 +5,7 @@ using System.Text; namespace LinqStudy { /// - /// Person自定义比较类 + /// Person自定义比较器 /// 各属性均同,则相等.有一个Null值则不相等。 /// public class PersonEqual : IEqualityComparer diff --git a/LinqStudy/Models/PersonEqualId.cs b/LinqStudy/Models/PersonEqualId.cs new file mode 100644 index 0000000..7a7b8c6 --- /dev/null +++ b/LinqStudy/Models/PersonEqualId.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace LinqStudy +{ + /// + /// Person 自定义ID比较器 + /// Id相同,则视为相同 + /// + public class PersonEqualId : IEqualityComparer + { + bool IEqualityComparer.Equals(Person x, Person y) + { + if (x==null || y==null) + { + return false; + } + + return x.Id == y.Id; + } + + int IEqualityComparer.GetHashCode(Person obj) + { + return (obj.Id).GetHashCode(); + } + } +} diff --git a/LinqStudy/Models/StudentOverriteEquals.cs b/LinqStudy/Models/StudentOverriteEquals.cs new file mode 100644 index 0000000..86fa9b5 --- /dev/null +++ b/LinqStudy/Models/StudentOverriteEquals.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace LinqStudy +{ + /// + /// 重写比较方法的学生类 + /// + public class StudentOverriteEquals + { + public int Id { get; set; } + + public string Name { get; set; } + + public int Age { get; set; } + + public override bool Equals(object obj) + { + var other = obj as StudentOverriteEquals; + if (other == null) + { + return false; + } + + return Id == other.Id; + } + + public override int GetHashCode() + { + return this.Id.GetHashCode(); + } + } +}