You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

401 lines
13 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Data;
using System.Data.SqlTypes;
using System.Data.Common;
using Xunit;
using LinqStudy.IEnumerableDemo;
namespace LinqStudy.Test.LinqToObject
{
/// <summary>
/// 转换运算符
/// </summary>
public class TypeConvertTest
{
#region AsEnumeralbe
/// <summary>
/// AsEnumeralbe操作符:将IEnumerable<T>输入序列转换成IEnumerable<T>的输出序列
/// 主要用于将一个实现了IEnumerable<T>接口的对象转换成一个标准的IEnumerable<T>接口对象。
/// 在Linq中、不同领域的Linq实现都有自己专属的操作符。
/// </summary>
[Fact]
public void AsEnumeralbe_Test()
{
var dt = GetDataTable();
//DataTable 使用方法,须有添加 System.Data.DataSetExtensions 引用
var students = dt.AsEnumerable().FirstOrDefault();
Assert.NotNull(students);
}
#endregion
#region AsQueryable
/// <summary>
/// 主要应用与Linq to sql
/// </summary>
[Fact]
public void AsQueryable_Test()
{
//
}
#endregion
#region OfType
/// <summary>
/// OfType从序列中筛选指定类型的元素并构建一个序列。
/// </summary>
[Fact]
public void OfType_Test()
{
//动态数组做为数据源
ArrayList ints = new ArrayList() { 1, "2", 3, "4", 5 };
var values = from i in ints.OfType<int>()
select i;
Assert.Equal(new List<int>() { 1, 3, 5 }, values.ToList());
}
#endregion
#region Cast
/// <summary>
/// Cast将数据源中元素强制转换成指定的类型。
/// 数据源null或存在不能转换的元素则异常。
/// </summary>
[Fact]
public void Cast_Test()
{
//动态数组做为数据源
ArrayList ints = new ArrayList() { "1", "2", "3", "4", "5" };
var values = ints.Cast<string>();
Assert.Equal(new List<string>() { "1", "2", "3", "4", "5" }, values.ToList());
}
[Fact]
public void Cast_ArgumentNullException_Test()
{
//动态数组做为数据源
ArrayList ints = null;
Assert.Throws<ArgumentNullException>(() => {
ints.Cast<string>();
});
}
[Fact]
public void Cast_InvalidCastException_Test()
{
//动态数组做为数据源
ArrayList ints = new ArrayList() { 1, "2", 3, "4" };
Assert.Throws<InvalidCastException>(() => {
ints.Cast<string>().ToList();
});
}
#endregion
#region ToList
/// <summary>
/// ToList将IEnumerable<T>转换为List<T>, 立即执行。
/// 特别注意:此操作破坏"延迟执行",变为立即执行;
/// 结果为数据源的一个快照,独立保存在内存中,不 受数据源变化的影响。
/// </summary>
[Fact]
public void ToList_Test()
{
List<string> email = new List<string>() { "abc@163.com", "bcd@126.com", "111@163.com" };
var query = email.Where(q => q.Contains("@163.")).ToList();
Assert.Equal(new List<string>() { "abc@163.com", "111@163.com" }, query);
}
[Fact]
public void ToList_DataSource_Change_Test()
{
List<string> email = new List<string>() { "abc@163.com", "bcd@126.com", "111@163.com" };
//延迟执行机制
var query1 = email.Where(q => q.Contains("@163."));
//ToList 变成立即执行,保存数据源的一个“快照”
var query2 = email.Where(q => q.Contains("@163.")).ToList();
//数据源变化
email.Add("test@163.com");
//延迟执行,反映数据源变化
Assert.Equal(new List<string>() { "abc@163.com", "111@163.com", "test@163.com" }, query1.ToList());
//ToList不受数据源变化影响
Assert.Equal(new List<string>() { "abc@163.com", "111@163.com" }, query2);
}
/// <summary>
/// 引用类型的数据源ToList之后形成的新序列是数据源的“完全新副本”的新对象。
/// 数据源与新序列元素的引用,不是同一个对象。
/// </summary>
[Fact]
public void ToList_ReferenceType_DataSource_Test()
{
List<Person> persons = PersonManager.GetPersons();
var person2 = persons.ToList();
//元素对象不是同一个元素
Assert.NotSame(persons, person2);
}
#endregion
#region ToDictionary
/// <summary>
/// ToDictionar转换字典立即执行并保存快照。
/// </summary>
[Fact]
public void ToDictionary_keySelector_Test()
{
List<Person> persons = new List<Person>()
{
new Person() {Id=1, Name="gaofeng",Age = 32 },
new Person() {Id=2, Name="zhangsan",Age = 25 },
};
var dic = persons.ToDictionary(p => p.Id);
Assert.Equal(1, dic[1].Id);
Assert.Equal(2, dic[2].Id);
}
[Fact]
public void ToDictionary_keySelector_comparer_Test()
{
List<Person> persons = new List<Person>()
{
new Person() {Id=1, Name="gaofeng",Age = 32 },
new Person() {Id=2, Name="zhangsan",Age = 25 },
};
var dic = persons.ToDictionary<Person, int>(p => p.Id, EqualityComparer<int>.Default);
Assert.Equal("gaofeng", dic[1].Name);
Assert.Equal("zhangsan", dic[2].Name);
}
[Fact]
public void ToDictionary_keySelector_elementSelector_Test()
{
List<Person> persons = new List<Person>()
{
new Person() {Id=1, Name="gaofeng",Age = 32 },
new Person() {Id=2, Name="zhangsan",Age = 25 },
};
var dic = persons.ToDictionary(p => p.Id, s => s.Name);
Assert.Equal("gaofeng", dic[1]);
Assert.Equal("zhangsan", dic[2]);
}
[Fact]
public void ToDictionary_keySelector_elementSelector_comparer_Test()
{
List<Person> persons = new List<Person>()
{
new Person() {Id=1, Name="gaofeng",Age = 32 },
new Person() {Id=2, Name="zhangsan",Age = 25 },
};
var dic = persons.ToDictionary(p => p.Id, s => s.Name, EqualityComparer<int>.Default);
Assert.Equal("gaofeng", dic[1]);
Assert.Equal("zhangsan", dic[2]);
}
[Fact]
public void ToDictionary_ArgumentException_Test()
{
List<Person> persons = new List<Person>()
{
new Person() {Id=1, Name="gaofeng",Age = 32 },
new Person() {Id=1, Name="zhangsan",Age = 25 },
};
Assert.Throws<ArgumentException>(() => {
persons.ToDictionary(p => p.Id, s => s.Name);
});
}
[Fact]
public void ToDictionary_ArgumentNullException_Test()
{
List<Person> persons = new List<Person>()
{
new Person() {Id=1, Name=null,Age = 32 },
new Person() {Id=1, Name="zhangsan",Age = 25 },
};
Assert.Throws<ArgumentNullException>(() => {
persons.ToDictionary(p => p.Name, s => s.Name);
});
}
[Fact]
public void ToDictionary_DataSource_NullException_Test()
{
List<Person> persons = null;
Assert.Throws<ArgumentNullException>(() => {
persons.ToDictionary(p => p.Name, s => s.Name);
});
}
#endregion
#region ToLookup
/// <summary>
/// ToLookup根据指定的键选择器函数从IEnumerable<T>创建Lookup<T>
/// Lookup<T>对象表示一个一对多的字典定义了一个由键和序列组成的元组类似GroupJoin返回的结果。
/// </summary>
[Fact]
public void ToLookup_Test()
{
var persons = new List<Employee>()
{
new Employee(){ Id=1, Name="gaofeng",Emails=new List<string>(){"a1@163.com","a2@163.com","a3@163.com"} },
new Employee(){ Id=1, Name="zhangsan",Emails=new List<string>(){ "b1@163.com", "b2@163.com", "b3@163.com" } },
new Employee(){ Id=2, Name="gaofeng2",Emails=new List<string>(){"c1@163.com","c2@163.com","c3@163.com"} },
new Employee(){ Id=2, Name="zhangsan2",Emails=new List<string>(){ "d1@163.com", "d2@163.com", "d3@163.com" } },
};
var lookup = persons.ToLookup(q => q.Id);
var group2 = lookup[2];
var group2_count = group2.Count();
Assert.Equal(2,group2_count);
}
[Fact]
public void ToLookup_keySelector_comparer_Test()
{
var persons = new List<Employee>()
{
new Employee(){ Id=1, Name="gaofeng",Emails=new List<string>(){"a1@163.com","a2@163.com","a3@163.com"} },
new Employee(){ Id=1, Name="zhangsan",Emails=new List<string>(){ "b1@163.com", "b2@163.com", "b3@163.com" } }
};
var lookup = persons.ToLookup(q => q.Id,EqualityComparer<int>.Default);
var group1_firstEmail = lookup[1].FirstOrDefault().Emails.FirstOrDefault() ;
Assert.Equal("a1@163.com", group1_firstEmail);
}
[Fact]
public void ToLookup_keySelector_elementSelector_Test()
{
var persons = new List<Employee>()
{
new Employee(){ Id=1, Name="gaofeng",Emails=new List<string>(){"a1@163.com","a2@163.com","a3@163.com"} },
new Employee(){ Id=1, Name="zhangsan",Emails=new List<string>(){ "b1@163.com", "b2@163.com", "b3@163.com" } }
};
var lookup = persons.ToLookup(q => q.Id, e=>e.Emails);
var group1_Emails = lookup[1].FirstOrDefault();
var group1_Emails_first = group1_Emails.FirstOrDefault();
Assert.Equal("a1@163.com", group1_Emails_first);
}
[Fact]
public void ToLookup_keySelector_elementSelector_comparer_Test()
{
var persons = new List<Employee>()
{
new Employee(){ Id=1, Name="gaofeng",Emails=new List<string>(){"a1@163.com","a2@163.com","a3@163.com"} },
new Employee(){ Id=1, Name="zhangsan",Emails=new List<string>(){ "b1@163.com", "b2@163.com", "b3@163.com" } }
};
var lookup = persons.ToLookup(q => q.Name, e => e.Emails,EqualityComparer<string>.Default);
var group1_Emails = lookup["gaofeng"].FirstOrDefault();
var group1_Emails_first = group1_Emails.FirstOrDefault();
Assert.Equal("a1@163.com", group1_Emails_first);
}
#endregion
#region private
private DataTable GetDataTable()
{
DataTable dt = new DataTable();
DataColumn col_id = new DataColumn("Id");
col_id.AllowDBNull = false;
col_id.AutoIncrementSeed = 1;
col_id.AutoIncrement = true;
col_id.AutoIncrementStep = 1;
col_id.DataType = typeof(int);
DataColumn col_name = new DataColumn("Name");
col_name.AllowDBNull = true;
col_name.AutoIncrement = false;
col_name.DataType = typeof(string);
col_name.DefaultValue = string.Empty;
DataColumn col_age = new DataColumn("Age");
col_age.AllowDBNull = false;
col_age.AutoIncrement = false;
col_age.DataType = typeof(int);
col_age.DefaultValue = 20;
dt.Columns.Add(col_id);
dt.Columns.Add(col_name);
dt.Columns.Add(col_age);
var row_one = dt.NewRow();
row_one[1] = "王高峰";
row_one[2] = 21;
var row_2 = dt.NewRow();
row_2[1] = "王向前";
row_2[2] = 32;
dt.Rows.Add(row_one);
dt.Rows.Add(row_2);
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
}
}