C#基础与进阶扩展合集-进阶篇(持续更新)

目录

本文分两篇,基础篇点击: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工作

15、深度解析await关键字

16、Task常用方法

17、ValueTask

18、异步方法的异常处理

三、版本新增 

1、范围运算符 

2、字符串格式控制 

3、数字分隔符 

4、小数点前后保留格式 


本文分两篇,基础篇点击:C#基础与进阶扩展合集-基础篇

二、进阶扩展

1、Predicate

拥有一个或多个泛型参数并返回一个 bool 值,常用于对 collection 进行一组条件检索,类似于Func。

举例:Predicate pre=m=>m.Id==2;

2、设置C#语言版本

工程文件 x.csproj中修改

PropertyGroup节点内添加子节点:

<LangVersion>latest</LangVersion>

3、ListCollectionView过滤集合

使用ListCollectionView类构造函数注入列表

通过该类的 Filter属性过滤集合

            List<Animal> animals = new List<Animal>() { new Animal(1,"ani1"),new Animal(2,"动物2") };
            List<Bear> bears = new List<Bear>();
            var tmp = animals.Adapt<List<Bear>>();
            tmp.ForEach(m => m.Description = "Animal adapt bear...");
            
            ListCollectionView view=new 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.Adapt<Bear>();
            Console.WriteLine(bear.Age.ToString());
            Console.WriteLine(bear.Description.ToString());
            Console.WriteLine("************************");
            Bear bear1=new 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.Name=="ConTest")
      str = item.ConnectionString;
}

8、Linq常用语句

定义LINQ扩展方法的一个类是System.Linq名称空间中的Enumerable;

Linq常用语句,详细讲解点击:C#-关于LINQ 

select:以指定形式返回

Where查询特点条件(方式1:from in;方式2:Lambda表达式)

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()方法让集合类以并行方式查询,该方法扩展了IEnumerable<TSource>接口,返回ParallelQuery<TSource>类;

示例如下,示例中并行LINQ所用时间约90ms,普通LINQ所用时间约为420ms,可以看出并行LINQ加快了代码运行速度

var list=Enumerable.Range(0, 5000_0000).Select(x => Random.Shared.Next(100)).ToList();
Stopwatch sw = Stopwatch.StartNew();
var avera= list.AsParallel().Where(m=>m<50).Select(m=>m).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);
        }
    }
    else
        Console.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、Span<T>实现切片

1、Span<T>,可快速访问托管与非托管的连续内存,如数组、长字符串;

2、可实现对数组部分进行访问或切片,不会复制数组元素,是从span中直接访问的,切片的两种方式①构造函数传递数组的开头与结尾;②Slice方法传递开头索引,提取到数组末尾;

3、可使用Span改变值,除了索引访问更改,还提供方法有:Clear()、填充Fill()、复制CopyTo()(不推荐,目标span不够大会抛异常)、复制推荐TryCopyTo()(span不够大不抛异常,而是返回false);

4、若只需对数组片段进行读访问,可使用ReadOnlySpan<T>;

int[] c = { 1, 3, 5, 8 };
Span<int> span = new Span<int>(c);
Span<int> span1= new Span<int>();
span[1] = 11;
span.Clear();
span.Fill(11);
Span<int> span2 = new Span<int>(c,0,3);
Span<int> span3 = span.Slice(0,3);   //切片
ReadOnlySpan<int> span4 = new(c);   //只读变量
if (!span.TryCopyTo(span3))
    Console.WriteLine("Argument");

14、数组池减少GC工作

         通过ArrayPool类(名称空间System.Buffers)使用数组池,可减少垃圾收集器的工作,ArrayPool管理一个数组池,数组可以从这租借,并返回池中,内存在ArrayPool中管理。

创建ArrayPool<T>,调用静态Create()方法;

使用预定义共享池,通过访问Shared属性

从池中租用内存,可调用Rent()方法,(池中数组元素数量最低16,且都是成倍增加);

内存(数组)返回到池中,调用Return()方法,可指定返回池之前是否清除该数组(false,下次租用数组的人可读取数据);

ArrayPool<int> arrayPool = ArrayPool<int>.Create(maxArrayLength: 100, maxArraysPerBucket: 10);
int[] arr = ArrayPool<int>.Shared.Rent(10);
arr[15] = 15;
Console.WriteLine($"Len={arr.Length}\tarr[15]={arr[15]}");//输出Len=16    arr[15]=15
ArrayPool<int>.Shared.Return(arr,true);
Console.WriteLine(arr[15]);//输出0

15、深度解析await关键字

await通常与async一同使用来实现异步编程,async没有await搭配使用将毫无意义;

使用Task任务的GetAwaiter()方法,返回一个TaskAwaiter<T>类型对象,该对象的OnCompleted()方法实现了INotifyCompletion接口,在任务完成时调用;

await实际就是编译器把await关键字后的所有代码放进了OnCompleted()方法的代码块中。

        public static void Main(string[] args)
        {
            TestAsync();
            Console.ReadLine();
        }
        public static async void TestAsync()
        {
            var awaiter = MyAsync().GetAwaiter();
            awaiter.OnCompleted(() =>
            {
                Console.WriteLine($"MyAsync ended....");
            });
            //await MyAsync();
            //Console.WriteLine("MyAsync ended.....");
        }
        public static async Task<string> MyAsync()
        {
            Thread.Sleep(100);
            Console.WriteLine(nameof(MyAsync));
            return nameof(MyAsync);
        }

16、Task常用方法

GetAwaiter()方法,用于await关键字的实现,详细如上;

ContinueWith()方法,用于延续任务;

WhenAll()静态方法,用于等待所有任务结束;

WhenAny()静态方法,用于等待任意一个任务结束;

17、ValueTask

C#7新增可用作await的新类型,ValueTask是一个结构,相对于Task具有性能上的优势,因为其在堆上没有对象;

18、异步方法的异常处理

若调用异步方法没有等待,try/catch不会捕获异常,因为在抛出异常前,就已经执行完毕了,若要捕获异常,需await等待异步方法。

        static void PutError()
        {
            try
            {
               await ThrowExcp();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
        static async Task ThrowExcp()
        { 
            await Task.Delay(1000);
            throw new Exception("Exception.....");
        }

三、版本新增 

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位

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/208952.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mysql多表查询 子查询

目录 关联查询——cross join 概述&#xff1a; 关联查询 inner join 概述&#xff1a; 关联查询 outher join 概述&#xff1a; inner join 和outher join 的区别 子查询 IN 概述 IN 分析 子查询 exists exists 分析 SQL之母 - SQL自学网站SQL自学网站http://sqlmo…

冒个泡!OceanBase亮相 2023 新加坡金融科技节

近日&#xff0c;OceanBase 亮相 Singapore Fintech Festival 2023&#xff08;2023 新加坡金融科技节&#xff09;&#xff01;本届新加坡金融科技节于 2023 年 11 月 15 日至 17 日在新加坡博览展览中心举行&#xff0c;展会期间&#xff0c;OceanBase 得到了众多金融科技机构…

2023-12-01 AIGC-自动生成ppt的AI工具

摘要: 2023-12-01 AIGC-自动生成ppt-记录 自动生成ppt: BoardMix boardmix 一键生成ppt boardmix是一款基于云的ai设计软件&#xff0c;允许创建用于各种目的的自定义演示文稿、ai绘画&#xff0c;ai生成思维导图等。以下是它的一些功能&#xff1a; 可定制的模板 - 它有一个…

无人机助力电力设备螺母缺销智能检测识别,python基于YOLOv5开发构建电力设备螺母缺销小目标检测识别系统

传统作业场景下电力设备的运维和维护都是人工来完成的&#xff0c;随着现代技术科技手段的不断发展&#xff0c;基于无人机航拍飞行的自动智能化电力设备问题检测成为了一种可行的手段&#xff0c;本文的核心内容就是基于YOLOv7来开发构建电力设备螺母缺销检测识别系统&#xf…

从0开始学习JavaScript--JavaScript ES6 模块系统

JavaScript ES6&#xff08;ECMAScript 2015&#xff09;引入了官方支持的模块系统&#xff0c;使得前端开发更加现代化和模块化。本文将深入探讨 ES6 模块系统的各个方面&#xff0c;通过丰富的示例代码详细展示其核心概念和实际应用。 ES6 模块的基本概念 1 模块的导出 ES…

提高Idea编码速度和插件自用推荐

非常推荐 Easy Javadoc 一款注释生成器&#xff0c;很好使~免费&#xff0c;配合使用腾讯、百度之类的翻译免费额度完全够用了&#xff0c;印象中是50万字符每月。下图是使用快捷键生成的注释&#xff08;我采用鼠标侧面按键&#xff0c;随手一按很方便&#xff09; Chinese …

MySQL 基础、进阶、运维的学习笔记

1. MySQL 基础篇 1.1 MySQL 概述 1.1.1 数据库相关概念 数据库(Database, 简称 DB): 存储数据的仓库&#xff0c;数据是有组织的进行存储。 数据库管理系统(Database Management System, 简称 DBMS): 操作和管理数据库的大型软件。 SQL(Structured Query Language, 简称 S…

万界星空科技MES生产管理系统的主要功能

万界星空科技MES/云MES生产管理系统主要包括以下功能模块&#xff1a; 生产计划管理&#xff1a;根据订单和生产计划&#xff0c;制定详细的调度表和车间生产经营计划&#xff0c;将生产计划和客户订单转化为具体的生产经营计划&#xff0c;消除有效的日常运营&#xff0c;大大…

macOS本地调试k8s源码

目录 准备工作创建集群注意点1. kubeconfig未正常加载2. container runtime is not running3. The connection to the server 172.16.190.132:6443 was refused - did you specify the right host or port?4. 集群重置5.加入子节点 代码调试 准备工作 apple m1芯片 安装vmwa…

计算机毕业设计 基于SpringBoot的敬老院管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

熬夜会秃头——beta冲刺Day2

这个作业属于哪个课程2301-计算机学院-软件工程社区-CSDN社区云这个作业要求在哪里团队作业—beta冲刺事后诸葛亮-CSDN社区这个作业的目标记录beta冲刺Day2团队名称熬夜会秃头团队置顶集合随笔链接熬夜会秃头——Beta冲刺置顶随笔-CSDN社区 目录 一、团队成员会议总结 1、成员…

力扣225-用队列实现栈

文章目录 力扣225-用队列实现栈示例代码实现总结收获 力扣225-用队列实现栈 示例 代码实现 class MyStack {Queue<Integer>queue1;Queue<Integer>queue2;public MyStack() {queue1new LinkedList<Integer>();queue2new LinkedList<Integer>();}public…

webGL开发学科演示项目方案

开发学科演示项目需要考虑到教育目标、互动性和用户体验。以下是一个可能的技术方案&#xff0c;可用于实现这样的项目&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.WebGL 框架&#xff1a; 选择…

管理Windows资产新方式:SSH协议

配置默认shell&#xff0c;需要管理员权限运行powershell执行下面命令&#xff1a; New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -F…

CentOS或RHEL安装vscode

下载rpm安装包 网络下载或者下载到本地再上传到服务器&#xff0c;点击访问国内下载地址&#xff0c;不需要积分curl -fOL https://github.com/coder/code-server/releases/download/v4.19.1/code-server-4.19.1-amd64.rpm安装 rpm -i code-server-4.19.1-amd64.rpm关闭和禁用…

力扣题:字符的统计-12.2

力扣题-12.2 [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 力扣题1&#xff1a;423. 从英文中重建数字 解题思想&#xff1a;有的单词通过一个字母就可以确定&#xff0c;依次确定即可 class Solution(object):def originalDigits(self, s):""":typ…

人工智能-优化算法之学习率调度器

学习率调度器 到目前为止&#xff0c;我们主要关注如何更新权重向量的优化算法&#xff0c;而不是它们的更新速率。 然而&#xff0c;调整学习率通常与实际算法同样重要&#xff0c;有如下几方面需要考虑&#xff1a; 首先&#xff0c;学习率的大小很重要。如果它太大&#xf…

Linux系统之centos7编译安装Python 3.8

前言 CentOS (Community Enterprise Operating System) 是一种基于 Red Hat Enterprise Linux (RHEL) 进行源代码再编译并免费提供给用户的 Linux 操作系统。 CentOS 7 采用了最新的技术和软件包&#xff0c;并提供了强大的功能和稳定性。它适用于各种服务器和工作站应用场景&a…

postgresql-shared_buffers参数详解

shared_buffers 是 PostgreSQL 中一个非常关键的参数&#xff0c;用于配置服务器使用的共享内存缓冲区的大小。这些缓冲区用于存储数据页&#xff0c;以便数据库可以更快地访问磁盘上的数据。 这个参数在 PostgreSQL 的性能方面有着重要的影响。增加 shared_buffers 可以提高数…

spring boot mybatis TypeHandler 看源码如何初始化及调用

目录 概述使用TypeHandler使用方式在 select | update | insert 中加入 配置文件中指定 源码分析配置文件指定Mapper 执行query如何转换 结束 概述 阅读此文 可以达到 spring boot mybatis TypeHandler 源码如何初始化及如何调用的。 spring boot 版本为 2.7.17&#xff0c;my…
最新文章