亳州市城乡建设局网站,巴西网站后缀,深圳企业网站建设费用,深圳个人形象设计工作室目录
本文分两篇#xff0c;基础篇点击#xff1a;C#基础与进阶扩展合集-基础篇
二、进阶扩展
1、Predicate
2、设置C#语言版本
3、ListCollectionView过滤集合
4、Adapt适配器
5、值类型与引用类型
6、程序设置当前项目工作目录
7、获取App.config配置文件中的值
…目录
本文分两篇基础篇点击C#基础与进阶扩展合集-基础篇
二、进阶扩展
1、Predicate
2、设置C#语言版本
3、ListCollectionView过滤集合
4、Adapt适配器
5、值类型与引用类型
6、程序设置当前项目工作目录
7、获取App.config配置文件中的值
8、Linq常用语句
9、并行LINQ
10、Mutex互斥及防止App多开
11、Monitor设置等待资源时间
12、扩展方法实现解构
13、Span实现切片
14、数组池减少GC工作
三、版本新增
1、范围运算符
2、字符串格式控制
3、数字分隔符
4、小数点前后保留格式 本文分两篇基础篇点击C#基础与进阶扩展合集-基础篇 二、进阶扩展
1、Predicate 拥有一个或多个泛型参数并返回一个 bool 值常用于对 collection 进行一组条件检索类似于Func。 举例Predicate premm.Id2; 2、设置C#语言版本 工程文件 x.csproj中修改 PropertyGroup节点内添加子节点: LangVersionlatest/LangVersion 3、ListCollectionView过滤集合 使用ListCollectionView类构造函数注入列表 通过该类的 Filter属性过滤集合 ListAnimal animals new ListAnimal() { new Animal(1,ani1),new Animal(2,动物2) };ListBear bears new ListBear();var tmp animals.AdaptListBear();tmp.ForEach(m m.Description Animal adapt bear...);ListCollectionView viewnew ListCollectionView(tmp);view.Filter i ((Bear)i).ID 2;foreach (var animal in view)MessageBox.Show(((Bear)animal).Name); 4、Adapt适配器 安装NutGet包Mapster 可理解成转换器适配器适配的是不同类间相同的名称不论字段或属性必须为值类型或字符串类型只要名字相同都适配给目的对象 注意即使名称相同属性或字段也不能适配成方法 Animal animal new Animal(18);Bear bear animal.AdaptBear();Console.WriteLine(bear.Age.ToString());Console.WriteLine(bear.Description.ToString());Console.WriteLine(************************);Bear bear1new Bear();Console.WriteLine(bear1.Age.ToString());Console.WriteLine(bear1.Description.ToString());Console.WriteLine(*************************);Banana banana animal.Adapt(new Banana());Console.WriteLine(banana.Description); 5、值类型与引用类型 值类型变量直接保存其数据作为类的字段成员变量时跟随其所属的实例存储也就是存储在堆中作为方法中的局部变量时存储在栈上 引用类型变量保存其数据的引用地址分配在栈中具体数据(实例)部署在托管堆中 值类型结构体数值类型bool型用户定义的结构体枚举可空类型 引用类型数组用户定义的类、接口、委托object字符串 引用类型string string a A;string b a;Console.WriteLine($a:{a}\tb:{b});a B;Console.WriteLine($a:{a}\tb:{b}); string为引用类型上面示例看出string像值类型 实际上是由于运算符的重构所导致的结果。当a被重新赋值时.NET为a在托管堆上重新分配了一块内存。这样做的目的是使字符串类型与通俗意义上讲的字符串更接地气。 引用类型数组 数组元素为值类型时在托管堆中一次性分配全部值类型空间堆中栈并自动初始化 元素为 引用类型时先在托管堆分配一次空间此时不会自动初始化任何元素均为null。等到有代码初始化某个元素的时这个引用类型元素的存储空间才会被分配在托管堆上 6、程序设置当前项目工作目录 Directory.SetCurrentDirectory(Path.GetDirectoryName(typeof(Test).Assembly.Location)); 7、获取App.config配置文件中的值 1、获取appSettings节点值 ConfigurationManager.AppSettings[key]; 2、获取connectionStrings节点值: var list ConfigurationManager.ConnectionStrings; string str; foreach (ConnectionStringSettings item in list) { if(item.NameConTest) str item.ConnectionString; } 8、Linq常用语句
定义LINQ扩展方法的一个类是System.Linq名称空间中的Enumerable
Linq常用语句详细讲解点击C#-关于LINQ select以指定形式返回 Where查询特点条件方式1from in方式2Lambda表达式 Order排序1、descending 降序2、ascending 升序 OfType查询特定类型 Join合并两集合通过指定键返回指定结构类型集合 GroupJoin:俩集合通过指定键分组 Reverse反转集合元素顺序 GroupBy按指定键对自身分组 Any / All 判断是否任意一个/全部满足条件 Skip跳过指定数量元素 Take拿取指定数量元素 Count获取元素个数 Sum、Average、Max、Min获取集合总值、平均值、最大值、最小值 Concat连接集合 Distinct去重去重类中某个字段需实现IEqualityComparer接口 ElementAt获取指定索引元素与[ ]类似 First/Single、Last获取集合中第一个、最后一个元素(如果集合中包含多个元素使用Single会报错) ToDictionary将集合转换为字典 ToList 将集合转换为List SequenceEqual判断两个集合是否相等 9、并行LINQ System.Linq名称空间中包含的类ParallelEnumerable可将查询的工作拆分到多个处理器上同时运行的多个线程中 通常可使用AsParallel方法让集合类以并行方式查询该方法扩展了IEnumerableTSource接口返回ParallelQueryTSource类 示例如下示例中并行LINQ所用时间约90ms普通LINQ所用时间约为420ms可以看出并行LINQ加快了代码运行速度 var listEnumerable.Range(0, 5000_0000).Select(x Random.Shared.Next(100)).ToList();
Stopwatch sw Stopwatch.StartNew();
var avera list.AsParallel().Where(mm50).Select(mm).Average();
sw.Stop();
Stopwatch sw2 Stopwatch.StartNew();
var avera2 list.Where(m m 50).Select(m m).Average();
sw2.Stop();
Console.WriteLine(sw.Elapsed.TotalMilliseconds);//约90ms
Console.WriteLine(sw2.Elapsed.TotalMilliseconds);//约420ms 10、Mutex互斥及防止App多开 1、继承自WaitHandle类抽象基类用于等待一个信号的设置有静态方法WaitOne、WaitAll、WaitAny 2、Mutex互斥锁可定义互斥名称所以可用于跨进程的同步操作因为操作系统可识别有名称的互斥在不同进程间共享 3、Mutex构造函数中可指定互斥是否最初应由主调线程拥有、定义互斥名称、获取互斥是否已存在的信息 用法1跨进程互斥实现进程间同步未命名互斥只能用于跨线程
Mutex mutext new Mutex(false,MyConsole);
mutext.WaitOne();
Console.WriteLine(${Process.GetCurrentProcess().ProcessName}:\tStart......);
Console.ReadLine();
mutext.ReleaseMutex();
Console.WriteLine(${Process.GetCurrentProcess().ProcessName}:\tEnd.......); 用法2防止App重复开启
Mutex mutext new Mutex(false,MyConsole,out bool createNew);
if (!createNew)return;
11、Monitor设置等待资源时间 lock关键字是由Monitor类实现抛出异常也会解锁如下 Monitor.Enter(_obj);try{Count--;}finally { Monitor.Exit(_obj); } Monitor相对于lock的优点在于使用Monitor的TryEnter方法其中可传递一个超时值用于指定等待被锁定的最长时间若_obj被锁定TryEnter方法将布尔型的引用参数设置为true并同步的访问_obj锁定状态若另一个线程锁定_obj时间超过指定时间TryEnter将bool引用参数置为false线程将不再等待而是去执行其它操作如下 Monitor.TryEnter(_obj, 2000, ref _lockTaken);if (_lockTaken){try{Console.WriteLine(Thread.CurrentThread.Name :\t obj lock.....);Thread.Sleep(5000);Console.WriteLine(Thread.CurrentThread.Name :\t obj release.....);}finally{Monitor.Exit(_obj);}}elseConsole.WriteLine(Timeout,Run other.....);
12、扩展方法实现解构
了解扩展方法点击扩展方法定义与使用 创建Deconstruct方法也称解构器将分离部分放入out参数中这里使用扩展方法实现解构示例如下 Stu stu new Stu(98, Auston);
stu.Deconstruct(out int score, out string name);
Console.WriteLine(${name}:{score});static class StuExtension
{public static void Deconstruct(this Stu stu, out int score, out string name){score stu.Score;name stu.Name;}
}13、SpanT实现切片 1、SpanT可快速访问托管与非托管的连续内存如数组、长字符串 2、可实现对数组部分进行访问或切片不会复制数组元素是从span中直接访问的切片的两种方式①构造函数传递数组的开头与结尾②Slice方法传递开头索引提取到数组末尾 3、可使用Span改变值除了索引访问更改还提供方法有:Clear()、填充Fill、复制CopyTo()不推荐目标span不够大会抛异常、复制推荐TryCopyTospan不够大不抛异常而是返回false; 4、若只需对数组片段进行读访问可使用ReadOnlySpanT; int[] c { 1, 3, 5, 8 };
Spanint span new Spanint(c);
Spanint span1 new Spanint();
span[1] 11;
span.Clear();
span.Fill(11);
Spanint span2 new Spanint(c,0,3);
Spanint span3 span.Slice(0,3); //切片
ReadOnlySpanint span4 new(c); //只读变量
if (!span.TryCopyTo(span3))Console.WriteLine(Argument);
14、数组池减少GC工作 通过ArrayPool类名称空间System.Buffers使用数组池可减少垃圾收集器的工作ArrayPool管理一个数组池数组可以从这租借并返回池中内存在ArrayPool中管理。 创建ArrayPoolT调用静态Create方法 使用预定义共享池通过访问Shared属性 从池中租用内存可调用Rent方法(池中数组元素数量最低16且都是成倍增加) 内存数组返回到池中调用Return方法可指定返回池之前是否清除该数组false下次租用数组的人可读取数据 ArrayPoolint arrayPool ArrayPoolint.Create(maxArrayLength: 100, maxArraysPerBucket: 10);
int[] arr ArrayPoolint.Shared.Rent(10);
arr[15] 15;
Console.WriteLine($Len{arr.Length}\tarr[15]{arr[15]});//输出Len16 arr[15]15
ArrayPoolint.Shared.Return(arr,true);
Console.WriteLine(arr[15]);//输出0 三、版本新增
C#9新增顶级语句;
字符串的范围除SubString方法C#8新增hat(^)、范围运算符[..];
1、范围运算符 string rangstr hello,auston! ; Console.WriteLine(rangstr[..5]);//范围运算符 Console.WriteLine(rangstr[7^2]);//hat^运算符从索引7往前数第2个字符 2、字符串格式控制 DateTime t DateTime.Now; Console.WriteLine(${t:D});//字符串格式控制 3、数字分隔符 int a 2_2_2;//使用数字分隔符提高代码可读性编译器会忽略下划线 Console.WriteLine(${a:c}); 4、小数点前后保留格式 double d 22.336_6; Console.WriteLine(${d:###.##});//小数点后四舍五入保留2位 Console.WriteLine(${d:000.00});//小数点前保留3位后保留2位