c#发展

首页 » 常识 » 预防 » C中的is真的是越来越强大,越来
TUhjnbcbe - 2020/11/24 15:51:00
一:背景1.讲故事

最近发现C#7之后的is是越来越看不懂了,乍一看花里胡哨的,不过当我静下心来仔细研读,发现这is是越来越短小精悍,而且还特别语义化,那怎是一个爽字了得??,这一篇就和大家简单聊一聊。

二:C#7之前的is如何使用1.类型兼容性检测

相信学过C#的朋友都会知道is是干嘛的,而且还经常和as一起比较,前者一般做兼容性检测,后者一般做兼容性转换,这里我就举个例子吧:

staticvoidMain(string[]args){objectslot=newSlot(){ClothesName="上衣"};if(slotisSlot){Console.WriteLine($"slotis{nameof(Slot)}");}if(slotisIComparable){Console.WriteLine($"slotis{nameof(IComparable)}");}}publicclassSlot:IComparable{publicstringClothesName{get;set;}publicintCompareTo(objectobj){return0;}}

从这个例子可以看到,object类型的slot和Slot,IComparable都是类型兼容的,非常简单。

2.遗憾的地方

然而在实际编码中,我相信有很多朋友都会在后续的过程中用到slot实例,而上面的这个例子,即使我用is检测到了是Slot类型,最后我还是要将objectslot强转成Slot类型,做了一次检测,又做了一个强转,这就很奇葩了,如下代码:

if(slotisSlot){varquery=(Slot)slot;Console.WriteLine($"slotis{nameof(Slot)},ClothesName={query.ClothesName}");}

除非有毛病才写这样的代码,干嘛不直接用as尝试性转换将两步合为一步走呢?修改代码如下:

varquery=slotasSlot;if(query!=null){Console.WriteLine($"slotis{nameof(Slot)},ClothesName={query.ClothesName}");}

这就导致很多场景下,is都被as替代了,搞的is成了一个空架子,如果is能合并as的功能,那就????了,我觉得这个急需增强。

三:C#7之后的is如何使用

也终于在C#7之后对is进行了翻天覆地的语法糖改造,导致你初看已经不明白啦??????,下面我就一一举例来说明吧。

1.is和复杂类型/简单类型的结合

现在就来看一下怎么用新is解决刚才两次转换的问题,如下代码:

objectslot=newSlot(){ClothesName="上衣"};if(slotisSlotquery){Console.WriteLine($"slotis{nameof(Slot)},ClothesName={query.ClothesName}");}

这段代码表面意思是:先用is检测slot是否为Slot类型,如果是就赋值给Slot类型的query变量,哈哈,有点意思吧,为了验证是否如我所说,用反编译工具看看。

ILSpy反编译DnSpy反编译

可以看到,在实操中,编译器都用as进行了还原,不过从代码流畅性来看,ILSpy更????一点。

除了和类实例比较之外,还可以和int,string,tuple...进行比较,代码如下:

objecte=;//字符串比较if(eis"hello"){}//整形比较if(eis10){}//tuple比较if(eis(10,20)){}2.is和null的结合

大家在写sql的时候判断某一个字段是否为null,通常都会这样写:usernameisnull或者usernameisnotnull,哈哈,这种写法也被引入到C#中了,有意思吧,上代码:

objecte=;if(eisnull){Console.WriteLine("eisnull");}if(eisnotnull){Console.WriteLine("eisnotnull");}

这么语义化的写法在C#中看到是不是有点不习惯,那为啥在sql中就习以为常呢?其实反编译过来也没啥,就是一个==判断,如下代码:

3.is和and,or的结合

现在大家都看到了is通常是放在if语句中,既然在if语句中,那肯定有很多的逻辑判断,这就需要结合and,or构建非常复杂的逻辑关系,不要眼花哦。

objecte=;if(eis=and=){Console.WriteLine($"e={e}果然大于并且小于");}if(eisoror){Console.WriteLine($"e={e}是在,,三个数字中");}if(eisnotnullandnot""){Console.WriteLine($"e={e},模拟!string.IsNullOrEmpty功能");}

可以看到最后的:eisnotnullandnot""其实等价于!string.IsNullOrEmpty,是不是有点意思哈。

这里有一点要提醒的是,上面的e在编译器层面都是object类型,如果你想在编译器层面使用int运作,还是用例子1的方式转换一下哈,如下图所示:

4.is和var的结合

当is和var结合起来就更????了,可以实现在if判断的过程中生成临时变量,如下代码:

inte=;if(eisvarii=i=){Console.WriteLine($"e={i}果然大于并且小于");}

上面代码中的i就是一个临时变量,后面做的一切业务逻辑都是基于i这个临时变量的,如果还没有领会到精粹,没关系,我举一个项目中的例子吧。。。

我们公司是搞衣物洗涤自动化,也需要对线下传输线上的衣服进行自动化上挂,取走和衣物组合搭配,举个例子:找到刚好挂了一件裤子L一件上衣L总衣服个数=2的挂孔号,要是还没听懂就算了,直接上代码说话。

classProgram{staticvoidMain(string[]args){varslotList=newListSlot(){newSlot(){SlotID=1,ClothesID=10,ClothesName="上衣",SizeName="L"},newSlot(){SlotID=1,ClothesID=20,ClothesName="裤子",SizeName="M"},newSlot(){SlotID=1,ClothesID=11,ClothesName="皮带",SizeName="X"},newSlot(){SlotID=2,ClothesID=30,ClothesName="上衣",SizeName="L"},newSlot(){SlotID=2,ClothesID=40,ClothesName="裤子",SizeName="L"}};//找到刚好挂了一件裤子L一件上衣L总衣服个数=2的挂孔号varquery=slotList.GroupBy(m=m.SlotID).Where(m=m.Where(n=n.SizeName=="L").ToList()isvarclothesListclothesList.Count(k=k.ClothesName=="裤子")is1clothesList.Count(k=k.ClothesName=="上衣")is1m.Key==2).ToDictionary(k=k.Key,v=v.ToList());}publicclassSlot{publicintSlotID{get;set;}publicintClothesID{get;set;}publicstringClothesName{get;set;}publicstringSizeName{get;set;}}}

重点在于上面代码的m.Where(n=n.SizeName=="L").ToList()isvarclothesList,这里的clothesList就是临时变量,它存放了所有尺寸L的衣物,后续的检索都是基于这个clothesList,是不是大大提高了检索速度~~~

四:总结

我觉得is的功能增强早就该出现了,现在终于搞定了,越来越人性化,键盘敲击次数越来越少,头发也不落了,甚至又开始第二春了,总的来说还是那句话,C#大法????。

预览时标签不可点收录于话题#个上一篇下一篇
1
查看完整版本: C中的is真的是越来越强大,越来