元素操作符

master
bicijinlian 6 years ago
parent 4c2a6d48eb
commit ee3f628442

@ -18,10 +18,6 @@
</PackageReference>
</ItemGroup>
<ItemGroup>
<Folder Include="ExpressionTree\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LinqStudy\LinqStudy.csproj" />
</ItemGroup>

@ -451,5 +451,114 @@ namespace LinqStudy.Test.LinqToObject
Assert.Throws<InvalidOperationException>(singleOrDefalutAction);
}
#endregion
#region ElementAt
/// <summary>
/// ElementAt返回集合中给定索引(索引从0开始)处的元素,延迟执行。
/// </summary>
[Fact]
public void ElementAt_Test()
{
List<Person> peoples = new List<Person>()
{
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);
}
/// <summary>
/// ArgumentNullException异常数据源为Null时引发。
/// </summary>
[Fact]
public void ElementAt_ArgumentNullException_Test()
{
List<Person> peoples = null;
Action queryAction = () => peoples.ElementAt(0);
Assert.Throws<ArgumentNullException>(queryAction);
}
/// <summary>
/// ArgumentOutOfRangeException异常指定索引超出序列范围时引发。
/// </summary>
[Fact]
public void ElementAt_ArgumentOutOfRangeException_Test()
{
List<Person> peoples = new List<Person>()
{
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<ArgumentOutOfRangeException>(queryAction);
}
#endregion
#region ElementAtOrDefault
/// <summary>
/// ElementAtOrDefault获取指定索引处的元素或如果超出索引范围时返回默认项延迟执行。
/// </summary>
[Fact]
public void ElementAtOrDefault_ElementAt()
{
List<Person> peoples = new List<Person>()
{
new Person(){ Id=1, Name="wanggaofeng", Age=33}
};
var queryItem = peoples.ElementAtOrDefault(0);
var queryItemName = queryItem.Name;
Assert.Equal("wanggaofeng", queryItemName);
}
/// <summary>
/// 超出索引范围,返回默认项。
/// 注意引用和可空类型返回null
/// </summary>
[Fact]
public void ElementAtOrDefault_Default()
{
List<Person> peoples = new List<Person>() { };
var queryItem = peoples.ElementAtOrDefault(2);
Assert.Null(queryItem);
}
[Fact]
public void ElementAtOrDefault_ArgumentNullException()
{
List<Person> peoples = null;
Action queryAction = () => peoples.ElementAtOrDefault(0);
Assert.Throws<ArgumentNullException>(queryAction);
}
/// <summary>
/// 查询不到数据,不异常
/// </summary>
[Fact]
public void ElementAtOrDefault_QueryEmpty_NoArgumentNullException()
{
List<Person> peoples = new List<Person>();
var queryItme = peoples.ElementAtOrDefault(5);
Assert.Null(queryItme);
}
#endregion
}
}

@ -0,0 +1,307 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Xunit;
using FluentAssertions;
namespace LinqStudy.Test.LinqToObject
{
/// <summary>
/// 量词操作符
/// </summary>
public class QuantifierTest
{
#region Any
/// <summary>
/// Andy序列中是否存在任一满足条件的项为加快判断速度立即执行
/// </summary>
[Fact]
public void Any_Test()
{
List<Person> peoples = new List<Person>()
{
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);
}
/// <summary>
/// 立即执行
/// </summary>
[Fact]
public void Any_Immediately_Test()
{
List<Person> peoples = new List<Person>()
{
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);
}
/// <summary>
/// 重载方法:查询表达式
/// </summary>
[Fact]
public void Any_Overload_Test()
{
List<Person> peoples = new List<Person>()
{
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);
}
/// <summary>
/// ArgumentNullException异常
/// </summary>
[Fact]
public void Any_ArgumentNullException_Test()
{
List<Person> peoples =null;
Action anyQueryAction =() => peoples.Any(q => q.Id >= 2);
Assert.Throws<ArgumentNullException>(anyQueryAction);
}
#endregion
#region All
/// <summary>
/// All序列中是否所有项都满足条件
/// 立即执行
/// </summary>
[Fact]
public void All_Test()
{
List<Person> peoples = new List<Person>()
{
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);
}
/// <summary>
/// 立即执行
/// </summary>
[Fact]
public void All_Immediately_Test()
{
List<Person> peoples = new List<Person>()
{
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);
}
/// <summary>
/// 重载方法:查询表达式
/// </summary>
[Fact]
public void All_Overload_Test()
{
List<Person> peoples = new List<Person>()
{
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);
}
/// <summary>
/// ArgumentNullException异常
/// </summary>
[Fact]
public void All_ArgumentNullException_Test()
{
List<Person> peoples = null;
Action anyQueryAction = () => peoples.All(q => q.Id >= 2);
Assert.Throws<ArgumentNullException>(anyQueryAction);
}
#endregion
#region Contains
/// <summary>
/// Contains序列中是否包含指定的项
/// 立即执行
/// </summary>
[Fact]
public void Contains_Test()
{
List<int> arr = new List<int>() {1,2,3,4,5 };
var anyQuery = arr.Contains(2);
Assert.True(anyQuery);
}
/// <summary>
/// 不包含时返回false
/// </summary>
[Fact]
public void Contains_No_Test()
{
List<int> arr = new List<int>() { 1, 2, 3, 4, 5 };
var anyQuery = arr.Contains(100);
Assert.False(anyQuery);
}
/// <summary>
/// 引用类型的包含,指引用的对象是同一个对象。
/// 属性值全部相等,但引用地址不同,则不包含。
/// </summary>
[Fact]
public void Contains_Reference_No_Test()
{
List<Person> peoples = new List<Person>()
{
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);
}
/// <summary>
/// 引用类型,包含:引用地址相同。
/// </summary>
[Fact]
public void Contains_Reference_Yes_Test()
{
List<Person> peoples = new List<Person>()
{
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);
}
/// <summary>
/// 立即执行
/// </summary>
[Fact]
public void Contains_Immediately_Test()
{
List<Person> peoples = new List<Person>()
{
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);
}
/// <summary>
/// 重载方法:使用自定义比较器
/// 虽然大部分属性都不一样但是比较器认为Id属性相同即相等Contains就认为包含。
/// </summary>
[Fact]
public void Contains_Overload_Test()
{
List<Person> peoples = new List<Person>()
{
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);
}
/// <summary>
/// NullReferenceException 异常
/// </summary>
[Fact]
public void Contains_NullReferenceException_Test()
{
List<Person> peoples = null;
var people = new Person() { Id = 3, Name = "小清闲", Age = 88 };
Action anyQueryAction = () => peoples.Contains(people);
Assert.Throws<NullReferenceException>(anyQueryAction);
}
#endregion
}
}

@ -159,16 +159,16 @@ namespace LinqStudy.Test.LinqToObject
[Fact]
public void SequenceEqual_OverrideEquals_Test()
{
List<Student> sequence1 = new List<Student>()
List<StudentOverriteEquals> sequence1 = new List<StudentOverriteEquals>()
{
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<Student> sequence2 = new List<Student>()
List<StudentOverriteEquals> sequence2 = new List<StudentOverriteEquals>()
{
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
/// 提供自定义比较器
/// </summary>
[Fact]
public void Test()
public void SequenceEqual_CustomEqual_Test()
{
List<Person> sequence1 = new List<Person>()
{
@ -194,55 +194,5 @@ namespace LinqStudy.Test.LinqToObject
Assert.True(sequence1.SequenceEqual(sequence2, new PersonEqual()));
}
/// <summary>
/// 自定义Person比较器
/// Id相同则表示同一个对象
/// </summary>
private class PersonEqual : IEqualityComparer<Person>
{
bool IEqualityComparer<Person>.Equals(Person x, Person y)
{
if (x==null || y==null)
{
return false;
}
return x.Id == y.Id;
}
int IEqualityComparer<Person>.GetHashCode(Person obj)
{
return obj.Id.GetHashCode();
}
}
/// <summary>
/// 重写比较方法
/// </summary>
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();
}
}
}
}

@ -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
}
}

@ -9,10 +9,13 @@ using Xunit;
namespace LinqStudy.Test.LinqToObject
{
/// <summary>
/// where操作符:过滤查询条件
/// where操作符
/// </summary>
public class WhereTest
{
/// <summary>
/// where过滤查询条件
/// </summary>
[Fact]
public void Where_Test()
{
@ -28,8 +31,11 @@ namespace LinqStudy.Test.LinqToObject
Assert.Equal(2, age);
}
/// <summary>
/// ArgumentNullException 异常
/// </summary>
[Fact]
public void Where_Argm_Test()
public void Where_ArgumentNullException_Test()
{
List<Person> Persons = null;

@ -0,0 +1,35 @@
# 标准查询操作符
## 投影操作符
Select
### SelectMany
## 限制操作符
### Where
## 排序操作符
### OrderBy
## 联接操作符
## 分组操作符
## 串联操作符
## 聚合操作符
## 生成操作符
## 转换操作符
## 元素操作符
## 相等操作符
## 量词操作符
## 分割操作符

@ -1,8 +0,0 @@
using System;
namespace LinqStudy
{
public class Class1
{
}
}

@ -2,6 +2,9 @@ using System;
namespace LinqStudy
{
/// <summary>
/// 人
/// </summary>
public class Person
{
public int Id{get;set;}

@ -5,7 +5,7 @@ using System.Text;
namespace LinqStudy
{
/// <summary>
/// Person自定义比较
/// Person自定义比较
/// 各属性均同,则相等.有一个Null值则不相等。
/// </summary>
public class PersonEqual : IEqualityComparer<Person>

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace LinqStudy
{
/// <summary>
/// Person 自定义ID比较器
/// Id相同则视为相同
/// </summary>
public class PersonEqualId : IEqualityComparer<Person>
{
bool IEqualityComparer<Person>.Equals(Person x, Person y)
{
if (x==null || y==null)
{
return false;
}
return x.Id == y.Id;
}
int IEqualityComparer<Person>.GetHashCode(Person obj)
{
return (obj.Id).GetHashCode();
}
}
}

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace LinqStudy
{
/// <summary>
/// 重写比较方法的学生类
/// </summary>
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();
}
}
}
Loading…
Cancel
Save