溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

帶你了解C# 中的 is

發(fā)布時(shí)間:2020-10-29 19:07:26 來源:億速云 閱讀:336 作者:Leah 欄目:開發(fā)技術(shù)

帶你了解C# 中的 is ?針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。

1. 類型兼容性檢測

相信學(xué)過 C# 的朋友都會(huì)知道 is 是干嘛的,而且還經(jīng)常和 as 一起比較,前者一般做兼容性檢測,后者一般做兼容性轉(zhuǎn)換,這里我就舉個(gè)例子吧:

 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

從這個(gè)例子可以看到, object 類型的 slot 和 Slot, IComparable 都是類型兼容的,非常簡單。

2. 遺憾的地方

然而在實(shí)際編碼中,我相信有很多朋友都會(huì)在后續(xù)的過程中用到 slot 實(shí)例,而上面的這個(gè)例子,即使我用 is 檢測到了是 Slot 類型,最后我還是要 將 object slot 強(qiáng)轉(zhuǎn)成 Slot類型,做了一次檢測,又做了一個(gè)強(qiáng)轉(zhuǎn),這就很奇葩了,如下代碼:

 if (slot is Slot)
   {
    var query = (Slot)slot;
    Console.WriteLine($"slot is {nameof(Slot)}, ClothesName={query.ClothesName}");
   }

除非有毛病才寫這樣的代碼,干嘛不直接用 as 嘗試性轉(zhuǎn)換將兩步合為一步走呢? 修改代碼如下:

 var query = slot as Slot;

   if (query != null)
   {
    Console.WriteLine($"slot is {nameof(Slot)}, ClothesName={query.ClothesName}");
   }

帶你了解C# 中的 is

這就導(dǎo)致很多場景下,is 都被 as 替代了,搞的 is 成了一個(gè)空架子,如果 is 能合并 as 的功能,那就🐂👃了,我覺得這個(gè)急需增強(qiáng)。

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

也終于在 C#7 之后對 is 進(jìn)行了翻天覆地的語法糖改造,導(dǎo)致你初看已經(jīng)不明白啦😄😄😄,下面我就一一舉例來說明吧。

1. is 和 復(fù)雜類型/簡單類型 的結(jié)合

現(xiàn)在就來看一下怎么用新is 解決剛才兩次轉(zhuǎn)換的問題,如下代碼:

 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 變量,哈哈,有點(diǎn)意思吧,為了驗(yàn)證是否如我所說,用反編譯工具看看。

ILSpy 反編譯

帶你了解C# 中的 is

DnSpy 反編譯

帶你了解C# 中的 is

可以看到,在實(shí)操中,編譯器都用 as 進(jìn)行了還原,不過從代碼流暢性來看,ILSpy更🐂👃一點(diǎn)。

除了和類實(shí)例比較之外,還可以和 int,string,tuple ...進(jìn)行比較, 代碼如下:

 object e = 150;

   //字符串比較
   if (e is "hello") { }

   //整形比較
   if (e is 10) { }

   //tuple 比較
   if (e is (10, 20)) { }

2. is 和 null 的結(jié)合

大家在寫 sql 的時(shí)候判斷某一個(gè)字段是否為 null,通常都會(huì)這樣寫: 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#中看到是不是有點(diǎn)不習(xí)慣,那為啥在 sql 中就習(xí)以為常呢? 其實(shí)反編譯過來也沒啥,就是一個(gè) == 判斷,如下代碼:

帶你了解C# 中的 is

3. is 和 and ,or 的結(jié)合

現(xiàn)在大家都看到了 is 通常是放在 if 語句中,既然在 if 語句中,那肯定有很多的邏輯判斷,這就需要結(jié)合 and,or 構(gòu)建非常復(fù)雜的邏輯關(guān)系,不要眼花哦。

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 三個(gè)數(shù)字中");
   }

   if (e is not null and not "")
   {
    Console.WriteLine($"e={e},模擬 !string.IsNullOrEmpty 功能");
   }

帶你了解C# 中的 is

可以看到最后的: e is not null and not "" 其實(shí)等價(jià)于 !string.IsNullOrEmpty, 是不是有點(diǎn)意思哈。

這里有一點(diǎn)要提醒的是,上面的 e 在編譯器層面都是 object 類型,如果你想在 編譯器層面使用 int 運(yùn)作,還是用 例子1 的方式轉(zhuǎn)換一下哈,如下圖所示:

帶你了解C# 中的 is

4. is 和 var 的結(jié)合

當(dāng) is 和 var 結(jié)合起來就更&#128002;&#128067;了,可以實(shí)現(xiàn)在 if 判斷的過程中生成臨時(shí)變量,如下代碼:

 int e = 150;

   if (e is var i && i >= 100 && i <= 200)
   {
    Console.WriteLine($"e={i} 果然 大于 100 并且 小于 200");
   }

上面代碼中的 i 就是一個(gè)臨時(shí)變量,后面做的一切業(yè)務(wù)邏輯都是基于 i 這個(gè)臨時(shí)變量的,如果還沒有領(lǐng)會(huì)到精粹,沒關(guān)系,我舉一個(gè)項(xiàng)目中的例子吧。。。

我們公司是搞衣物洗滌自動(dòng)化,也需要對線下 傳輸線上的衣服進(jìn)行自動(dòng)化上掛,取走和衣物組合搭配,舉個(gè)例子:找到 剛好掛了一件褲子L && 一件上衣L && 總衣服個(gè)數(shù)=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 & 總衣服個(gè)數(shù)=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

重點(diǎn)在于上面代碼的 m.Where(n => n.SizeName == "L").ToList() is var clothesList ,這里的 clothesList 就是臨時(shí)變量,它存放了所有 尺寸L 的衣物,后續(xù)的檢索都是基于這個(gè) clothesList,是不是大大提高了檢索速度~~~

關(guān)于帶你了解C# 中的 is 問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

is
AI