服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C# 中的 is 真的是越来越强大越来越语义化(推荐)

C# 中的 is 真的是越来越强大越来越语义化(推荐)

2022-10-10 15:34一线码农 C#

这篇文章主要介绍了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;}
}

C# 中的 is 真的是越来越强大越来越语义化(推荐)

从这个例子可以看到, 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}");
 }

C# 中的 is 真的是越来越强大越来越语义化(推荐)

这就导致很多场景下,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}");
 }

C# 中的 is 真的是越来越强大越来越语义化(推荐)

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

ILSpy 反编译

C# 中的 is 真的是越来越强大越来越语义化(推荐)

DnSpy 反编译

C# 中的 is 真的是越来越强大越来越语义化(推荐)

可以看到,在实操中,编译器都用 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 中就习以为常呢? 其实反编译过来也没啥,就是一个 == 判断,如下代码:

C# 中的 is 真的是越来越强大越来越语义化(推荐)

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 功能");
 }

C# 中的 is 真的是越来越强大越来越语义化(推荐)

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

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

C# 中的 is 真的是越来越强大越来越语义化(推荐)

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; }
}
}

C# 中的 is 真的是越来越强大越来越语义化(推荐)

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

四:总结

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

更多高质量干货:参见我的 GitHub: dotnetfly

到此这篇关于C# 中的 is 真的是越来越强大越来越语义化的文章就介绍到这了,更多相关C# 中 is 内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/huangxincheng/archive/2020/09/30/13753658.html

  • C#
  • is
  • 延伸 · 阅读

    精彩推荐
    • C#C#中的 == 和equals()区别浅析

      C#中的 == 和equals()区别浅析

      这篇文章主要介绍了C#中的 == 和equals()的区别,对不同点进行了阐述,感兴趣的小伙伴们可以参考一下...

      C#教程网10572021-11-01
    • C#C#判断获取的是文件夹还是文件的实例

      C#判断获取的是文件夹还是文件的实例

      今天小编就为大家分享一篇C#判断获取的是文件夹还是文件的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

      晴雨阳-_-!!!8852022-07-27
    • C#C#实现在Form里面内嵌dos窗体的方法

      C#实现在Form里面内嵌dos窗体的方法

      这篇文章主要介绍了C#实现在Form里面内嵌dos窗体的方法,涉及C#针对Form窗体的设置及使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

      我心依旧4322021-10-24
    • C#C# 格式化字符串的实现代码

      C# 格式化字符串的实现代码

      这篇文章主要介绍了C# 格式化字符串的实现代码,需要的朋友可以参考下...

      flyingbread11082021-12-10
    • C#浅谈C# StringBuilder内存碎片对性能的影响

      浅谈C# StringBuilder内存碎片对性能的影响

      这篇文章主要介绍了浅谈StringBuilder内存碎片对性能的影响,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋...

      .NET骚操作11892022-08-30
    • C#关于C#中ajax跨域访问问题

      关于C#中ajax跨域访问问题

      最近做项目,需要跨域请求访问数据问题。下面通过本文给大家分享C#中ajax跨域访问代码详解,需要的朋友可以参考下...

      CDL_Darren7442022-01-05
    • C#C#实现TreeView节点拖拽的方法

      C#实现TreeView节点拖拽的方法

      这篇文章主要介绍了C#实现TreeView节点拖拽的方法,涉及C#针对TreeView节点的动态添加及移除技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

      99re12562021-10-26
    • C#C#添加、读取Word脚注尾注的方法

      C#添加、读取Word脚注尾注的方法

      这篇文章主要为大家详细介绍了C#添加、读取Word脚注尾注的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

      E-iceblue10752022-02-24