共计 3594 个字符,预计需要花费 9 分钟才能阅读完成。
一:背景
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# 大法????????。
更多高质量干货:参见我的 GitHub: dotnetfly