一:背景
1. 讲故事
上一篇跟大家聊到了Target-typed new
和 Lambda discard parameters
,看博客园和公号里的阅读量都达到了新高,甚是欣慰,不管大家对新特性是多头还是空头,起码还是对它抱有一种极为关注的态度,所以我的这个系列还得跟,那就继续开撸吧,今天继续带来两个新特性,更多新特性列表,请大家关注:新特性预览
二:新特性研究
1. Native ints
从字面上看貌似是什么原生类型ints,有点莫名其妙,还是看一看Issues
上举得例子吧:
1
2
3
|
Summary: nint i = 1; and nuint i2 = 2; Shipped in preview in 16.7p1. |
有点意思,还是第一次看到有nint这么个东西,应该就是C#9新增的关键词,好奇心爆棚,快来实操一下。
1
2
3
4
5
|
static void Main( string [] args) { nint i = 10; Console.WriteLine($ "i={i}" ); } |
从图中看,可以原样输出,然后用ILSpy查查底层IL代码,发现连IL代码都不用看。如下图:
从图中看原来 nint 就是 IntPtr 结构体哈,如果你玩过 C# 到 C++ 之间的互操作,我相信你会对Ptr再熟悉不过了,从这个 nint 上看,你不觉得C#团队对指针操作是前所未有的重视吗? 前有指针类型IntPtr
,后有内存段处理集合Span
,到现在直接提供关键词支持,就是尽最大努力让你在类型安全的前提下使用指针。
这就让我想起了前些天写的一篇互操作的文章,现在就可以用nint进行简化了,来段代码给大家看一下。
-
原来的写法:
123456789
[DllImport(
"ConsoleApplication1.dll"
, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
extern
static
IntPtr AddPerson(Person person);
static
void
Main(
string
[] args)
{
var person =
new
Person() { username =
"dotnetfly"
, password =
"123456"
};
var ptr = AddPerson(person);
var str = Marshal.PtrToStringAnsi(ptr);
}
- IntPtr -> nint 的写法
总的来说这个关键词不是最重要的,重要的是C#团队对指针操作抱有前所未有的重视,这是一个非常积极的信号。
2. Pattern matching improvements
模式匹配这个不算是什么新特性了,在本次C#9中也是继续得到了完善,可能有很多朋友对模式匹配不是很熟悉,毕竟是C#7才有的新玩法,后面几乎每一个新版本都在跟踪完善,我先科普一下吧。
模式匹配到底解决了什么问题
大家在编码的过程中,不可能遇不到 if/else 嵌套 if/else
的这种情况,有时候嵌套甚至达到5,6层之多,特别影响代码可读性,我就来YY个例子。
现在各个地方都在发不同面值的消费券,为了实现千人千面,消费券的发放规则如下:
性别 | 年龄 | 地区 | 面值 |
男 | <20 | 安徽 | 2000 |
男 | <40 | 上海 | 4000 |
男 | 剩余 | 剩余 | 3000 |
女 | <20 | 安徽 | 2500 |
女 | <60 | 安徽 | 1500 |
如果用传统的方式,你肯定要用各种花哨的if/else
来实现,如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
static decimal GetTicket( string sex, int age, string area) { if (sex == "男" ) { if (age < 20 && area == "安徽" ) { return 2000; } else { if (age < 40 && area == "上海" ) { return 4000; } else { return 3000; } } } else { if (age < 20 && area == "安徽" ) { return 2500; } if (age < 60 && area == "安徽" ) { return 1500; } } return 0; } |
这种代码可读性不是一般的差,就像大强子说的那样:看着都想打人。。。 问题来了,这代码还有救吗??? 当然有了,这就需要用Pattern matching
去简化,毕竟它就是为了这种问题而生的,修改后的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
static decimal GetTicket_Pattern( string sex, int age, string area) { return (sex, age, area) switch { ( "男" , < 20, "安徽" ) => 2000, ( "男" , < 40, "上海" ) => 4000, ( "男" , _, _) => 3000, ( "女" , < 20, "安徽" ) => 2500, ( "女" , < 60, "安徽" ) => 1500, _ => 0 }; } |
看到这种化简后的代码是不是非常惊讶,这就是 Pattern matching 要帮你解决的场景,接下来看看底层的IL代码是什么样子。
从图中看,这反编译后的代码比我手工写的还要烂,无力吐槽哈,当然 模式匹配 有各种千奇百怪的玩法,绝对让你瞠目结舌,更多玩法可参考官方文档:模式匹配
这个特性最重要的是你一定要明白它的客户群在哪里?
三: 总结
总的来说,这两个特性都是比较实用的,尤其是 Pattern matching
化解了你多少不得不这么写的烂代码,头发护理就靠它了,快来给它点个赞吧!
好了,先就这样吧,感谢您的阅读,希望本篇对你有帮助,谢谢。
以上就是c# 9.0新特性nint和Pattern matching的使用方法的详细内容,更多关于c# nint和Pattern matching的资料请关注服务器之家其它相关文章!
原文链接:https://www.cnblogs.com/huangxincheng/p/13111705.html