|
|
@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
<Query Kind="Statements">
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.CodeAnalysis.CSharp</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Configuration</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Configuration.Binder</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Configuration.CommandLine</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Configuration.EnvironmentVariables</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Configuration.FileExtensions</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Configuration.Ini</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Configuration.Json</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Configuration.UserSecrets</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Configuration.Xml</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.DependencyInjection</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Logging</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Logging.Configuration</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Microsoft.Extensions.Options</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>Newtonsoft.Json</NuGetReference>
|
|
|
|
|
|
|
|
<NuGetReference>xunit</NuGetReference>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.Configuration</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.Configuration.CommandLine</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.Configuration.EnvironmentVariables</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.Configuration.Memory</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.DependencyInjection</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.DependencyInjection.Extensions</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.FileProviders.Internal</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.FileProviders.Physical</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.Logging</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.Logging.Abstractions</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.Logging.Configuration</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.Options</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Microsoft.Extensions.Primitives</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Newtonsoft.Json</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Newtonsoft.Json.Converters</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Newtonsoft.Json.Linq</Namespace>
|
|
|
|
|
|
|
|
<Namespace>Newtonsoft.Json.Serialization</Namespace>
|
|
|
|
|
|
|
|
<Namespace>System.Threading.Tasks</Namespace>
|
|
|
|
|
|
|
|
<IncludePredicateBuilder>true</IncludePredicateBuilder>
|
|
|
|
|
|
|
|
<IncludeLinqToSql>true</IncludeLinqToSql>
|
|
|
|
|
|
|
|
<IncludeAspNet>true</IncludeAspNet>
|
|
|
|
|
|
|
|
</Query>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
数据切片学习
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
相关类及命名空间
|
|
|
|
|
|
|
|
System.ArraySegment 数组切片
|
|
|
|
|
|
|
|
System.Index 索引对象
|
|
|
|
|
|
|
|
System.Range 范围对象,不支持多维数组
|
|
|
|
|
|
|
|
System.Linq 结构化查询
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 切片语法糖:C# 8+支持
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ // ^ 表示倒数:从尾部向前数,并且从1开始,索引必须是正整数
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var names = new string[] { "潘安琪", "贺睿", "邹致远", "蔡子韬", "江睿", "范震南", "何詩涵", "郝岚", "尹震南", "萧詩涵" };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//倒数第1个:索引从1开始,而不是0开始(为0则异常)
|
|
|
|
|
|
|
|
Console.WriteLine($"倒数第1个:{names[^1]} ");
|
|
|
|
|
|
|
|
Console.WriteLine($"倒数第2个:{names[^2]} ");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ // .. 表示范围:[开始索引..结束索引]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var names = new string[] {"潘安琪", "贺睿", "邹致远", "蔡子韬", "江睿", "范震南", "何詩涵", "郝岚", "尹震南", "萧詩涵"};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//.. 表示所有
|
|
|
|
|
|
|
|
names[..].Dump();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//开始索引s.. 表示第s个开始,直到结尾
|
|
|
|
|
|
|
|
names[1..].Dump();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//开始索引s..结束索引e 表示第m个开始,直到s结束e(不包括e)
|
|
|
|
|
|
|
|
names[1..5].Dump();
|
|
|
|
|
|
|
|
names[0..1].Dump();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//与^组合使用
|
|
|
|
|
|
|
|
names[^2..].Dump(); //倒数第2个开始,直到结尾(倒数第2个和倒数第1个)
|
|
|
|
|
|
|
|
names[..^2].Dump(); //第1个开始,倒数第2个结束(去掉尾部2项)
|
|
|
|
|
|
|
|
names[5..^2].Dump(); //第6个开始,倒数第2个结束(去掉前面5个和尾部2项)
|
|
|
|
|
|
|
|
names[^2..^1].Dump(); //倒数第2个开始,倒数第1个结束(倒数第2个)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ // .. 范围:可用 Range 对象表示,第n个可用 System.Index 索引对象表示
|
|
|
|
|
|
|
|
var names = new string[] {"潘安琪", "贺睿", "邹致远", "蔡子韬", "江睿", "范震南", "何詩涵", "郝岚", "尹震南", "萧詩涵"};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
System.Range r1= ..;
|
|
|
|
|
|
|
|
names[r1].Dump();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
System.Range r2 = new System.Range(); //默认项数为0的切片,不是null而是Empty切片
|
|
|
|
|
|
|
|
names[r2].Dump();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var start = new Index(0);//第1个
|
|
|
|
|
|
|
|
var end = new Index(1,true); //倒序索引,倒数第1个
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//“索引对象” 组成 “范围对象”
|
|
|
|
|
|
|
|
var query = new System.Range(start,end);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//切片使用 “范围对象”
|
|
|
|
|
|
|
|
var segment = names[query];
|
|
|
|
|
|
|
|
segment.Dump();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
重要特性
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//1、切片是由原数组创建的新数组,两个数组本身互相独立、互不影响;
|
|
|
|
|
|
|
|
// 如果数据项是引用对象,因为两个数组虽然各自独立,但引用对象是同一个,这时引用对象本身的修改,会影响两个数组;
|
|
|
|
|
|
|
|
var ages = new int[] {1, 2, 3, 4, 5};
|
|
|
|
|
|
|
|
var s1 = ages[..2];
|
|
|
|
|
|
|
|
//改变切片项的值,原数组保持不变
|
|
|
|
|
|
|
|
s1[0]=-100;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//两个数组本身互相独立、互不影响
|
|
|
|
|
|
|
|
(ages[0] == s1[0]).Dump();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//数据项是引用对象,对引用对象的修改,都影响
|
|
|
|
|
|
|
|
var persons = new Person[]
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
new Person(){Name = "潘安琪", Age = 20},
|
|
|
|
|
|
|
|
new Person(){Name = "贺睿", Age = 36},
|
|
|
|
|
|
|
|
new Person(){Name = "邹致远", Age = 65},
|
|
|
|
|
|
|
|
new Person(){Name = "蔡子韬", Age = 85},
|
|
|
|
|
|
|
|
new Person(){Name = "江睿", Age = 24},
|
|
|
|
|
|
|
|
new Person(){Name = "范震南", Age = 29},
|
|
|
|
|
|
|
|
new Person(){Name = "何詩涵", Age = 11},
|
|
|
|
|
|
|
|
new Person(){Name = "郝岚", Age = 65},
|
|
|
|
|
|
|
|
new Person(){Name = "尹震南", Age = 85},
|
|
|
|
|
|
|
|
new Person(){Name = "萧詩涵", Age = 62},
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var segment = persons[1..3];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//persons和segment本身互相独立
|
|
|
|
|
|
|
|
//但 persons[1]segment[0] 是同一个 Person 地址,所以改变一个引用的 Person 时,另一个也引用了同一个对象自然就变
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//修改对象属性值
|
|
|
|
|
|
|
|
segment[0].Name="修改";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine($"名称相同:{segment[0].Name == persons[1].Name}");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
切片与System.Span<T> System.Memory<T> 组合使用
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//原数组使用AsSpan方法;而不应把切片直接给Span
|
|
|
|
|
|
|
|
//把切片直接给Span,此时切片与原数组独立,相当于Span了整个切片而与原数组脱离关系
|
|
|
|
|
|
|
|
var source = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//AsSpan方法,可以把指定切片语法的部分转为Span,这样原数据与Span相关,才能提高性能
|
|
|
|
|
|
|
|
var span1 = source.AsSpan(0..3);
|
|
|
|
|
|
|
|
Console.WriteLine($"Span是原数组的一部分, source[0]{(source[0]==span1[0]?"==":"!=")}span1[0]");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
切片与 “列表模式匹配”
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int[] source = new int[] { 1, 3, 5, 7, 9 };
|
|
|
|
|
|
|
|
//传统switch语句:switch (变量) => 变量在后,Case 分支语句,目的是选择执行Case分支语句块,无返回值。
|
|
|
|
|
|
|
|
switch (source)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case [var a, .., 5]://Case后可以使用各种模式匹配
|
|
|
|
|
|
|
|
//业务逻辑
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//模式匹配switch语句:判断量 switch (变量)=>变量在前,lamda分支语句,目的是选择执行lamda分支语句块,有返回值
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//使用弃元,放弃返回值
|
|
|
|
|
|
|
|
_ = source switch
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
[1, ..] => 2, //因为是lamda表达式,所以只能是单条返回语句.不能加{}执行多语句
|
|
|
|
|
|
|
|
[..] => 3,
|
|
|
|
|
|
|
|
_ => 2,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
//返回值给变量
|
|
|
|
|
|
|
|
int t = source switch
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
[1, .., 9] a => a[0],
|
|
|
|
|
|
|
|
int[] { Length: >= 5} item => item[4],
|
|
|
|
|
|
|
|
int[] =>1,
|
|
|
|
|
|
|
|
_ => 0,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//作为方法体,返回值给方法执行结果
|
|
|
|
|
|
|
|
static int GetSourceLabel<T>(IEnumerable<T> source) => source switch
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
string[] {Length:>0} =>1,
|
|
|
|
|
|
|
|
int[] i and [var a, ..] => 1,
|
|
|
|
|
|
|
|
Array array => 2,
|
|
|
|
|
|
|
|
ICollection<T>{Count:>0} collection => 2,
|
|
|
|
|
|
|
|
_ => 0,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Person
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
public string Name { get; set;}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public int Age {get;set;}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|