diff --git a/LinqStudy.Test/LinqToObject/SetsTest.cs b/LinqStudy.Test/LinqToObject/SetsTest.cs new file mode 100644 index 0000000..ec6fea3 --- /dev/null +++ b/LinqStudy.Test/LinqToObject/SetsTest.cs @@ -0,0 +1,226 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace LinqStudy.Test.LinqToObject +{ + /// + /// Sets 集合操作符 + /// 注意:集合操作为 “延迟执行”,数据源为null时均引发异常。 + /// + public class SetsTest + { + #region Distinct + + /// + /// Distinct:元素去重;延迟执行。 + /// 注意:值类型可以直接去重;引用类型比较的是引用而不是对象本身的属性等,可以提供自定义比较器。 + /// + [Fact] + public void Distinct_Test() + { + List array = new List() { 1, 2, 2, 3, 3, 3 }; + + var distinctItem = array.Distinct(); + var expected = new List() { 1, 2, 3 }; + + Assert.Equal(expected, distinctItem); + } + + /// + /// 引用类型:剔除同一个引用的重复项。 + /// + [Fact] + public void Distinct_Reference_Yes_Test() + { + var p1 = new Person() { Id = 2, Name = "小龙女", Age = 28 }; + var p2 = new Person() { Id = 4, Name = "杨过", Age = 32 }; + + List peoples = new List(); + peoples.Add(p1); + peoples.Add(p2); + + //添加对同一对象的多次引用 + peoples.Add(p1); + peoples.Add(p2); + + var totalCount = peoples.Count(); + var distinctCount = peoples.Distinct().Count(); + + Assert.Equal(4, totalCount); + Assert.Equal(2, distinctCount); + } + + [Fact] + public void Distinct_Reference_No_Test() + { + + List peoples = new List() + { + new Person() { Id = 1, Name = "小龙女", Age = 28 }, + new Person() { Id = 1, Name = "小龙女", Age = 28 }, + }; + + //虽然1、2两项对象属性完命相同,但是两个不同的对象(new两次),所以不是“重复项” + //去重后仍然是2项 + var distinctCount = peoples.Distinct().Count(); + + Assert.Equal(2, distinctCount); + } + + /// + /// 延迟执行 + /// + [Fact] + public void Distinct_Daley_Test() + { + List array = new List() { 1, 2, 2, 3, 3, 3 }; + + var distinctItem = array.Distinct(); + + array.Add(5); + + var expected = new List() { 1, 2, 3, 5 }; + + Assert.Equal(expected, distinctItem); + } + + /// + /// 重载:自定义比较器 + /// + [Fact] + public void Distinct_compare_Test() + { + List peoples = new List() + { + new Person(){ Id=1, Name="小龙女", Age=28}, + new Person(){ Id=1, Name="我不是龙女", Age=68}, + }; + + var distinctItem = peoples.Distinct(new PersonEqualityComparerById()); + + //虽然两项只有Id属性相等,其它属性均不同; + //但是因为自定义比较器内部,只比较Id即只要Id相同就认为同一对象。 + //所以去重后,只有一项(第一项,第二项被认为是重复项,被去除)。 + var distinctCount = distinctItem.Count(); + + var expected = 1; + Assert.Equal(expected, distinctCount); + } + #endregion + + #region Union + + /// + /// Union:取两个序列的并集,并去除重复项。 + /// 与SQL比较相似;Concat不去除重复项。 + /// + [Fact] + public void Union_Test() + { + var p1 = new Person() { Id = 1, Name = "杨过", Age = 32 }; + var p2 = new Person() { Id = 2, Name = "小龙女", Age = 28 }; + var p3 = new Person() { Id = 3, Name = "银花公主", Age = 16 }; + + List peoples1 = new List() + { + p1, + p2, + }; + List peoples2 = new List() + { + p1, + p3, + }; + + var act = peoples1.Union(peoples2); + + //因为"杨过"是重复的,所有总共有3项 + var totalCount = act.Count(); + + Assert.Equal(3, totalCount); + } + + /// + /// Union: 对同一数据源两次查询后,两次结果Union + /// 注意:同一数据源多次查询形成的序列项,均是对同一对象的引用。 + /// 项里保存的是引用地址,非对象本身。 + /// + [Fact] + public void Union_UseQuery_Test() + { + List peoples = new List() + { + new Person(){ Id=1, Name="张三丰", Age=230}, + new Person(){ Id=2, Name="小龙女", Age=28}, + new Person(){ Id=3, Name="银花公主", Age=16}, + new Person(){ Id=4, Name="杨过", Age=32}, + }; + + var peoples1 = peoples.Where(q => q.Id <= 3); + var peoples2 = peoples.Where(q => q.Age < 230); + + var act = peoples1.Union(peoples2); + + //前3项 + 后3项- 重复2项=4项 + var totalCount = act.Count(); + + Assert.Equal(4, totalCount); + } + + /// + /// Union重载: camparer + /// + [Fact] + public void Union_camparer_Test() + { + var p1 = new Person() { Id = 1, Name = "杨过", Age = 32 }; + var p2 = new Person() { Id = 2, Name = "小龙女", Age = 28 }; + var p3 = new Person() { Id = 2, Name = "我非龙女", Age = 77 }; + + List peoples1 = new List() + { + p1, + p2, + }; + List peoples2 = new List() + { + p1, + p3, + }; + + var act = peoples1.Union + ( + peoples2, + new PersonEqualityComparerById() + ) + .ToList(); + + //虽然P2和p3只有Id相同,其它不同;但自定义比较只看Id,所以P2和p3被认为是同一个对象。 + //结果集为:p1+p2 + var totalCount = act.Count(); + + Assert.Equal(2, totalCount); + } + + /// + /// 异常:ArgumentNullException + /// + [Fact] + public void Union_ArgumentNullException_Test() + { + List peoples1 = null; + List peoples2 = null; + + Action act = () => peoples1.Union + ( + peoples2 + ); + + Assert.Throws(act); + } + #endregion + } +} \ No newline at end of file