C# 中的 is 真的是越来越强大,越来越语义化
一:背景
1. 讲故事
最近发现 C#7 之后的 is 是越来越看不懂了,乍一看花里胡哨的,不过当我静下心来仔细研读,发现这 is 是越来越短小精悍,而且还特别语义化,那怎是一个爽字了得????,这一篇就和大家简单聊一聊。
二:C#7 之前的 is 如何使用
1. 类型兼容性检测
相信学过 C# 的朋友都会知道 is 是干嘛的,而且还经常和 as 一起比较,前者一般做兼容性检测,后者一般做兼容性转换,这里我就举个例子吧:
static void Main(string[] args){object slot = new Slot() { ClothesName = "上衣" };if (slot is Slot){Console.WriteLine($"slot is {nameof(Slot)}");}if (slot is IComparable){Console.WriteLine($"slot is {nameof(IComparable)}");}}public class Slot : IComparable{public string ClothesName { get; set; }public int CompareTo(object obj) {return 0;}}
从这个例子可以看到, object 类型的 slot 和 Slot, IComparable 都是类型兼容的,非常简单。
2. 遗憾的地方
然而在实际编码中,我相信有很多朋友都会在后续的过程中用到 slot 实例,而上面的这个例子,即使我用 is 检测到了是 Slot 类型,最后我还是要 将 object slot 强转成 Slot类型,做了一次检测,又做了一个强转,这就很奇葩了,如下代码:
if (slot is Slot){var query = (Slot)slot;Console.WriteLine($"slot is {nameof(Slot)}, ClothesName={query.ClothesName}");}
除非有毛病才写这样的代码,干嘛不直接用 as 尝试性转换将两步合为一步走呢?修改代码如下:
var query = slot as Slot;if (query != null){Console.WriteLine($"slot is {nameof(Slot)}, ClothesName={query.ClothesName}");}
这就导致很多场景下,is 都被 as 替代了,搞的 is 成了一个空架子,如果 is 能合并 as 的功能,那就????????了,我觉得这个急需增强。
三:C#7 之后的 is 如何使用
也终于在 C#7 之后对 is 进行了翻天覆地的语法糖改造,导致你初看已经不明白啦????????????,下面我就一一举例来说明吧。
1. is 和 复杂类型/简单类型 的结合
现在就来看一下怎么用新is 解决刚才两次转换的问题,如下代码:
object slot = new Slot() { ClothesName = "上衣" };if(slot is Slot query){Console.WriteLine($"slot is {nameof(Slot)}, ClothesName={query.ClothesName}");}
这段代码表面意思是:先用 is 检测 slot 是否为 Slot 类型,如果是就赋值给 Slot 类型的 query 变量,哈哈,有点意思吧,为了验证是否如我所说,用反编译工具看看。
ILSpy 反编译
DnSpy 反编译
可以看到,在实操中,编译器都用 as 进行了还原,不过从代码流畅性来看,ILSpy更????????一点。
除了和类实例比较之外,还可以和 int,string,tuple ...进行比较, 代码如下:
object e = 150;//字符串比较if (e is "hello") { }//整形比较if (e is 10) { }//tuple 比较if (e is (10, 20)) { }
2. is 和 null 的结合
大家在写 sql 的时候判断某一个字段是否为 null,通常都会这样写:username is null
或者 username is not null
,哈哈,这种写法也被引入到 C# 中了,有意思吧,上代码:
object e = 150;if (e is null){Console.WriteLine("e is null");}if (e is not null){Console.WriteLine("e is not null");}
这么语义化的写法在C#中看到是不是有点不习惯,那为啥在 sql 中就习以为常呢?其实反编译过来也没啥,就是一个 == 判断,如下代码:
3. is 和 and ,or 的结合
现在大家都看到了 is 通常是放在 if 语句中,既然在 if 语句中,那肯定有很多的逻辑判断,这就需要结合 and,or 构建非常复杂的逻辑关系,不要眼花哦。
object e = 150;if (e is >= 100 and <= 200){Console.WriteLine($"e={e} 果然 大于 100 并且 小于 200");}if (e is 100 or 150 or 200){Console.WriteLine($"e={e} 是在 100,150,200 三个数字中");}if (e is not null and not ""){Console.WriteLine($"e={e},模拟 !string.IsNullOrEmpty 功能");}
可以看到最后的: e is not null and not ""
其实等价于 !string.IsNullOrEmpty
, 是不是有点意思哈。
这里有一点要提醒的是,上面的 e 在编译器层面都是 object 类型,如果你想在 编译器层面使用 int 运作,还是用 例子1 的方式转换一下哈,如下图所示:
4. is 和 var 的结合
当 is 和 var 结合起来就更????????了,可以实现在 if 判断的过程中生成临时变量,如下代码:
int e = 150;if (e is var i && i >= 100 && i <= 200){Console.WriteLine($"e={i} 果然 大于 100 并且 小于 200");}
上面代码中的 i 就是一个临时变量,后面做的一切业务逻辑都是基于 i 这个临时变量的,如果还没有领会到精粹,没关系,我举一个项目中的例子吧。。。
我们公司是搞衣物洗涤自动化,也需要对线下 传输线上的衣服进行自动化上挂,取走和衣物组合搭配,举个例子:找到 刚好挂了一件裤子L && 一件上衣L && 总衣服个数=2 的 挂孔号
,要是还没听懂就算了,直接上代码说话。
class Program{static void Main(string[] args){var slotList = new List<Slot>(){new Slot() {SlotID=1, ClothesID=10,ClothesName="上衣", SizeName= "L" },new Slot() {SlotID=1, ClothesID=20,ClothesName="裤子", SizeName= "M" },new Slot() {SlotID=1, ClothesID=11,ClothesName="皮带", SizeName= "X" },new Slot() {SlotID=2, ClothesID=30,ClothesName="上衣", SizeName= "L" },new Slot() {SlotID=2, ClothesID=40,ClothesName="裤子", SizeName= "L" }};//找到 刚好挂了一件裤子L & 一件上衣L & 总衣服个数=2 的 挂孔号var query = slotList.GroupBy(m => m.SlotID).Where(m =>m.Where(n => n.SizeName == "L").ToList() is var clothesList &&clothesList.Count(k => k.ClothesName == "裤子") is 1 &&clothesList.Count(k => k.ClothesName == "上衣") is 1 &&m.Key == 2).ToDictionary(k => k.Key, v => v.ToList());}public class Slot{public int SlotID { get; set; }public int ClothesID { get; set; }public string ClothesName { get; set; }public string SizeName { get; set; }}}
重点在于上面代码的 m.Where(n => n.SizeName == "L").ToList() is var clothesList
,这里的 clothesList 就是临时变量,它存放了所有 尺寸L
的衣物,后续的检索都是基于这个 clothesList,是不是大大提高了检索速度~~~
四:总结
我觉得 is 的功能增强早就该出现了,现在终于搞定了,越来越人性化,键盘敲击次数越来越少,头发也不落了,甚至又开始第二春了,总的来说还是那句话,C# 大法????????。
C# 中的 is 真的是越来越强大,越来越语义化相关推荐
- G2:一个由纯 javascript 编写、强大的语义化图表生成工具
原名G2,现在更名AntV 阿里出了一套js库跟Highcharts类似,但还是有区别的highcharts在生成图片或PDF要发送请求到服务器上生成后返回.G2不需要,是不是very nice? G ...
- 也使得飞鸽传书2007的功能越来越强大!
自从飞鸽传书2007自发布以来,产品以其独特的设计.新颖的风格.完善的服务而受到了用户的好评,随着用户量的不断增加,用户在使用中给程序提了很多中肯的意见或建议,也使得飞鸽传书2007的功能越来越强大! ...
- 从iQOO Z1看vivo越来越强大的5G势能
5月19日,iQOO举行线上新品发布会,正式推出Z系列,并发布了首款Z系列产品--iQOO Z1.凭借天玑1000Plus+44W超快闪充+5G双卡双待+144Hz+Wi-Fi6+竞速屏等顶尖硬件组合 ...
- 从智能家居到智慧办公,HarmonyOS展现出越来越强大的全场景连接能力
9月13日,华为举行智慧办公新品发布会,进一步深化智慧办公产品布局. 本次发布会,华为不仅发布了全新的华为移动应用引擎,还带来了华为MateBook 13s.MateBook 14s笔记本电脑.华为M ...
- SQL Server中SELECT会真的阻塞SELECT吗?
在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.T ...
- java中的console是干什么的_[Java教程]javascript中,你真的会用console吗?
[Java教程]javascript中,你真的会用console吗? 0 2015-08-11 17:00:09 使用console进行性能测试和计算代码运行时间 对于前端开发人员,在开发过程中经常需 ...
- Java 中的 String 真的是不可变的吗
转载自 Java 中的 String 真的是不可变的吗 我们都知道 Java 中的 String 类的设计是不可变的,来看下 String 类的源码. public final class Str ...
- figma下载_如何在Figma中创建逼真的3D对象
figma下载 by Gbolahan Taoheed Fawale 通过Gbolahan Taoheed Fawale 如何在Figma中创建逼真的3D对象 (How to create reali ...
- 有关WEB前端中的语义化
作天在变卖大学书籍时也不晓得怎么的就想起语义化这个概念,于是乎也就花点时间搞搞它.语义化标记对于刚学web前端脚本语言的童鞋来说往往都没太 在意,哇哈哈,其实我也就算只比较老的菜鸟而已,本文不是说教, ...
最新文章
- PAT甲级1120 Friend Numbers:[C++题解]set去重且有序
- Java多线程之并发协作生产者消费者设计模式
- SHADER效果收集
- NYOJ 135 取石子(二)
- tomcat装死原因汇总
- 推荐系统知识梳理——协同过滤
- LeetCode Palindrome Linked List (回文链表)
- 【转】优化WebLogic 服务器性能参数
- 解决bootstrap模态框居中问题
- html语言空格怎么写,html的空格代码怎么写?
- 深入理解PHP内核(十二)函数-函数的定义、传参及返回值
- keil5的基本使用
- oc引导windows蓝屏_使用Opencore引导ubuntu以及Linux的步骤
- zencart模板分析
- git上传代码的账户名不是本人的问题
- 如何快速删除百度相关搜索中的关键词?
- 串口协议模板及其参数配置
- netty 错误 #[IllegalReferenceCountException: refCnt: 0, decrement: 1]
- 微信抢红包的方案_微信抢红包怎样才能抢到最大的告诉你一个方法
- 技术领导力1-CTO 能力、素质与战略类
热门文章
- T T[] toArray(T[] a);
- 斜率优化(CDQ分治,Splay平衡树):BZOJ 1492: [NOI2007]货币兑换Cash
- Struts 2.x No result defined for action 异常
- linkButton与Button 的click事件与onclientClick事件
- vscode配置、使用git
- Mybatis之设计模式之装饰者模式
- MySQL - Found option without preceding group in config file
- Windows Server 2012 DHCP 服务器中的新功能:故障转移和策略
- socket编程资料-网络收集
- erlang 编译之 to_core