C#中檢查null的語法糖

来源:https://www.cnblogs.com/podolski/archive/2022/04/23/16184027.html
-Advertisement-
Play Games

今天看到已經更新了devblogs,新增的C# 11的!!(用於檢查null的語法)經過非常長的討論,最後取消了。然後我又想起來null檢查,這個可以說一說。 函數參數null檢查 傳統寫法 寫一個函數的時候,最經典的檢查,估計也是大家最常使用的null檢查,應該是這樣的吧: public stat ...


今天看到已經更新了devblogs,新增的C# 11的!!(用於檢查null的語法)經過非常長的討論,最後取消了。然後我又想起來null檢查,這個可以說一說。

函數參數null檢查

傳統寫法

寫一個函數的時候,最經典的檢查,估計也是大家最常使用的null檢查,應該是這樣的吧:

public static void GetV1(string prompt)
{
    if (prompt is null) throw new ArgumentNullException(nameof(prompt));
    Console.WriteLine(prompt);
}

ThrowIfNull

這個寫起來也沒啥問題,但是總覺得有點不舒適。.NET 6在ArgumentNullException中新增了ThrowIfNull方法,可以寫的更優雅一點。

public static void GetV2(string prompt)
{
    ArgumentNullException.ThrowIfNull(prompt);
    Console.WriteLine(prompt);
} 

異常的時候,就會出現:System.ArgumentNullException: 'Value cannot be null. (Parameter 'prompt')'。這個是不是簡單了點?可是還是需要寫一行。

C# 11的!!語法(已經取消)

C# 11剛preview的時候,我就瞄到了這個特性,現在依然可以通過設置preview來進行啟用,但是以後正式發佈估計就不行了。

它通過在參數後面疊加!!表示此參數不可為空,運行時會自動進行檢查,如果是null就直接彈出錯誤。

public static void GetV3(string prompt!!)
{
    Console.WriteLine(prompt);
}

這個代碼會被編譯器翻譯成:

public static void GetV3(string prompt!!)
{
    if (prompt is null) {
        throw new ArgumentNullException(nameof(prompt));
    }
    Console.WriteLine(prompt);
}

這樣大家就可以專註於業務代碼,不需要經常考慮異常檢查了。至於為什麼這個東西最後還是被刪除了,可以從討論中看到一絲端倪,首先是感覺非常糾結於這個語法,兩個嘆號;然後就是已經有比較多的方式可以實現檢查了,這個東西是否有必要。反正最終是以後再討論了,不過也可以看出來C#語言工作組對語言的特性討論非常謹慎。

他們還討論了很多別的形式,每種都提出了各自的優缺點挺有意思的,能看出來有一點設計語言的嚴謹和小強迫症在,點贊~

void M(string s!!);
void M(string! s);
void M(string s!);
void M(notnull string s);
void M(string s ?? throw);
void M(string s is not null);
void M(checked string s);
void M(string s) where s is not null;

有關null的一些操作

說起這個,就順便說說c#處理null的另外幾個語法糖吧。

??

如果左邊是的null,那麼返回右邊的操作數,否則就返回左邊的操作數,這個在給變數賦予預設值非常好用。

int? a = null;
int b = a ?? -1;
Console.WriteLine(b);  // output: -1

??=

當左邊是null,那麼就對左邊的變數賦值成右邊的

int? a = null;
a ??= -1;
Console.WriteLine(a);  // output: -1

?.

當左邊是null,那麼不執行後面的操作,直接返回空,否則就返回實際操作的值。

using System;
public class C {
    public static void Main() {
        string i = null;
        int? length = i?.Length;
        Console.WriteLine(length ?? -1); //output: -1
    }
}

?[]

索引器操作,和上面的操作類似

using System;
public class C {
    public static void Main() {
        string[] i = null;
        string result = i?[1];
        Console.WriteLine(result ?? "null"); // output:null
    }
}

註意,如果鏈式使用的過程中,只要前面運算中有一個是null,那麼將直接返回null結果,不會繼續計算。下麵兩個操作會有不同的結果。

using System;
public class C {
    public static void Main() {
        string[] i = null;
        Console.WriteLine(i?[1]?.Substring(0).Length); //不彈錯誤
        Console.WriteLine((i?[1]?.Substring(0)).Length) // System.NullReferenceException: Object reference not set to an instance of an object.
    }
}

一些操作

//參數給予預設值
if(x == null) x = "str";
//替換
x ??= "str";


//條件判斷
string x;
if(i<3) 
    x = y;
else 
{  
    if(z != null) x = z; 
    else z = "notnull";
}
//替換
var x = i < 3 ? y : z ?? "notnull"


//防止對象為null的時候,依然執行代碼
if(obj != null) 
    obj.Act();
//替換
obj?.Act();

//Dictionary取值與賦值
string result;
if(dict.ContainKey(key))
{
    if(dict[key] == null) result = "有結果為null";
    else result = dict[key];
}
else 
    result = "無結果為null";
//替換
var result= dict.TryGetValue(key, out var value) ? value ?? "有結果為null" : "無結果為null";

結語

原來新定的C# 11提供了一個新的??,話說我個人還是挺喜歡這個特性的,不管以什麼形式出現吧,期待以後再見。

C#中為了處理null給我們準備了許多的語法糖,只能說非常簡便了。有很多人會說這個可讀性不好,或者覺得這是“茴字的幾種寫法”似的歪門邪道,我只能說,傳統的語法也不是說取消了,語言有發展,只要還是比較審慎的,我覺得還是一件好事。

參考資料

後記

一定要誇一下博客園,寫完這篇文章想登陸博客園發佈的時候,被登陸卡住了。彈出來和google一樣的驗證畫面,找紅綠燈找人行橫道什麼的,只能說我找了幾分鐘也沒找明白,我確信我已經點的正確了,所有的區塊,占上了有一點算不算?不知道也沒有反饋,就點呀點呀,密碼我已經按照要求設置的夠複雜了,還有必要通過這種反人類的東西來驗證嗎?不理解,京東阿裡之類的購物網站的驗證也就拖一下完事,這博客園的後臺估計比那些個地方還要敏感吧,贊一個!太贊了!

除非特殊說明,本作品由podolski創作,採用知識共用署名 4.0 國際許可協議進行許可。歡迎轉載,轉載請保留原文鏈接~喜歡的觀眾老爺們可以點下關註或者推薦~
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 圖像是 Web 應用中除文字外最普遍的媒體格式。 流行的 Web 靜態圖片有 JPEG、PNG、ICO、BMP 等。動態圖片主要是 GIF 格式。 為了節省圖片傳輸流量,大型互聯網公司還會定製特殊格式的圖片,WEBP 格式就是一個代表。 Python 除了數據分析,做圖片處理也是非常好用的。 ...
  • 前言 在一個Web應用中,通常會採用MVC設計模式實現對應的模型、視圖和控制器,其中,視圖是用戶看到並與之交互的界面。對最初的Web應用來說,視圖是由HTML元素組成的靜態界面;而後期的Web應用更傾向於使用動態模板技術,從而實現前後端分離和頁面的動態數據展示。Spring Boot框架為簡化項目的 ...
  • 最近的項目搗鼓msp430需要用到dac轉換以輸出模擬信號,項目代碼是接手前同事的 有些地方調試不通,以前沒有接觸過msp430晶元,更是沒搞過這種晶元io口時序驅動層的東西,甚至純c的都是頭一次作為工作正式用。沒辦法 萬事開頭難嘛 ,硬著頭皮網上到處翻資料 找晶元的手冊 找dac外設的寄存器說明, ...
  • 當我們電腦裡面的文本或者或者文件夾太多了,有時候想找到自己想要的文件,只能通過去搜索文件名,要是名字忘記了的話,那你也搜不了吧,當然你可通過尾碼名去搜索,但是通過搜索出來的文件只會更多,這還只是文件多的情況下。 如果文件名字基本一樣,只有序號不一樣呢?那特麽眼睛看瞎了估計還沒找到。 那麼我們可以用P ...
  • 前言 在實際開發中,經常需要將一組(不只一個)數據存儲起來,以便後邊的代碼使用。在VBA中有使用數組,可以把多個數據存儲 到一起,通過數組下標可以訪問數組中的每個元素。Python 中沒有數組,但是加入了更加強大的列表(list)。下麵就對列表的內 置方法進行介紹。 通過dir(list)可以查看列 ...
  • DQ41Y、DQ41F、DQ61Y、DQ61F低溫球閥適用於低溫液體貯運設備的管理系統,具有開關靈活、密封可靠的特點,也可用於其他低溫和深冷介質的管理系統。 ...
  • Q41H硬密封球閥適用於Class150~Class2500、PN16~PN160的各種管路上,用於截斷或接通管路中的介質。選用不同的材質,硬密封球閥可分別適用於非腐蝕型介質、弱腐蝕性介質、硝酸、醋酸、氧化性介質、尿素等多種介質,特別適用於含固體顆粒介質、料漿、煤粉、灰渣等苛刻工況。 ...
  • 練習模板(只包含了Swagger,Jwt可以直接練手):https://gitee.com/zh1446802857/swagger-multi-version-api.git Jwt在我的 認知里,是一套門鎖。別人(用戶)需要用到你的介面 的時候需要通過這個身份識別才可以使用。就像是一間房子,只有 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...