前言

在 C# 中,問號(?)遠不止是一個簡單的標點符號。隨着語言版本的迭代更新,C# 圍繞問號(?)發展出了一套強大而優雅的空值處理和條件表達機制。熟練掌握這些操作運算符不僅能大幅提升代碼的簡潔性和可讀性,還能有效避免惱人的空引用異常,構建更加健壯的應用程序。

可空類型修飾符(?)

在 C# 中,值類型(如int、long、bool、DateTime等)默認不能為null。使用 ? 修飾符,我們可以將值類型轉換為可空類型。

int notNullableInt;// 非空int類型默認為 0
            int? nullableInt = null;
            bool? nullableBool = null;
            long? nullableLong = null;
            DateTime? nullableDate = null;

            // 檢查是否有值
            if (nullableInt.HasValue)
            {
                Console.WriteLine($"整數值: {nullableInt.Value}");
            }
            else
            {
                Console.WriteLine("變量沒有值(為null)");
            }

Null 合併運算符(??)

Null 合併運算符(??)如果左邊的值不為null,則返回左邊的值,否則返回右邊的值。

static void Main(string[] args)
        {
            string userName1 = "小明";
            string userName2 = null;
            var getUserName = userName1 ?? userName2 ?? "默認用户";

            Console.WriteLine(getUserName); // 輸出: 小明

            string config1 = null;
            string config2 = null;
            string config3 = "DefaultConfig";
            string finalConfig = config1 ?? config2 ?? config3 ?? "FallbackConfig";
            Console.WriteLine(finalConfig); // 輸出: DefaultConfig
        }

Null 合併賦值運算符(??=)

C# 8.0 引入的運算符,僅當左操作數為null時,才將右操作數的值賦給左操作數。這是懶加載模式的理想選擇。

static void Main(string[] args)
        {
            string? name = null;
            name ??= "時光者";
            Console.WriteLine(name); // 時光者

            name ??= "大姚"; // 不改變
            Console.WriteLine(name); // 時光者


            //惰性初始化
            Dictionary<string, string>? cache = null;

            cache ??= new Dictionary<string, string>();
            cache["UserName"] = name;

            Console.WriteLine(cache["UserName"]);
        }

三元條件運算符(?:)

條件運算符(?:),又稱三元運算符,是一種簡潔的條件表達式形式。它對布爾表達式進行求值,並根據結果為true或false,選擇性地返回兩個表達式中的對應結果,為簡單條件判斷提供了一種比傳統if-else語句更緊湊、表達力更強的語法形式。

static void Main(string[] args)
        {
            int score = 80;
            string level = score >= 60 ? "Pass" : "Fail";
            Console.WriteLine(level);
        }

Null 條件成員訪問運算符 (?.)

Null 條件成員訪問運算符 (?.) 在訪問對象成員(屬性、方法、字段等)前先檢查對象是否為 null。如果對象為 null,整個表達式返回 null 而不會拋出 NullReferenceException;如果對象不為 null,則正常訪問成員。

static void Main(string[] args)
        {
            // 基本用法
            Person person = null;
            string name = person?.Name; // 不會拋出異常,name 為 null
            Console.WriteLine(name ?? "name is null"); // 輸出: name is null
        }

Null 條件索引訪問運算符 (?[])

Null 條件索引訪問運算符 (?[]) 在使用索引器訪問集合元素前先檢查集合對象是否為 null。如果集合為 null,整個表達式返回 null 而不會拋出異常;如果集合不為 null,則正常訪問索引位置的元素。

static void Main(string[] args)
        {
            List<string> names = null;
            string firstName = names?[0]; // 不會拋出異常,firstName 為 null
            Console.WriteLine(firstName ?? "No names available"); // 輸出: No names available

            // 初始化列表後訪問
            names = new List<string> { "時光者", "小袁", "大姚" };
            string secondName = names?[0]; // 安全訪問索引為0的元素
            Console.WriteLine(secondName); // 輸出: 時光者
        }

C#/.NET/.NET Core面試寶典

本文已收錄至C#/.NET/.NET Core面試寶典中,更新C#/.NET/.NET Core面試乾貨前往開源地址查看:

  • https://github.com/YSGStudyHards/DotNetGuide

C# 中 ?、??、??=、?: 、?. 、?[] 各種問號的用法和説明_操作數

C# 中 ?、??、??=、?: 、?. 、?[] 各種問號的用法和説明_運算符_02