C# 10:CallerArgumentExpression 特徵項

這篇筆記要整理的是 C# 10 新增的 CallerArgumentExpression 特徵項,同時也順便複習 Call* 家族的其他特徵項。


[CallerArgumentExpression] 特徵項可用來捕捉函式中的某個傳入參數的表達式,並將其表達式保存於另一個字串參數。範例:

Show(Math.Sqrt(9)); // 取平方根

void Show(double num,
          [CallerArgumentExpression("num")] string expr = null)
    => Console.WriteLine(expr + $" = {num}");

執行結果:

Math.Sqrt(9) = 3

從這個例子可以看得出來,呼叫端傳入 num 參數的時候是怎麼寫的,當時的寫法就會被捕捉並保存於字串參數 expr。由於不需要呼叫端傳入 expr 參數,故此參數在宣告的時候必須給一個預設值(通常是 null)。此外,[CallerArgumentExpression] 可以在同一個方法當中使用多次,亦即可捕捉多個參數。

這項功能對於測試、驗證、或輸出記錄(log)訊息的場合特別有用。例如:

IsTrue(1 + 1 == 3);

void IsTrue(bool value,
[CallerArgumentExpression("value")] string expr = null)
{
    if (!value)
        throw new ArgumentException($"{expr} 不是真的!");
}

執行結果:

System.ArgumentException: 1 + 1 == 3 不是真的!

試試看:https://dotnetfiddle.net/etlTWD


這裡不妨順便複習一下其他 Caller* 特徵項(從 C# 5 便已提供):

Log("發生錯誤");
void Log(
    string msg,
    [CallerMemberName] string caller = null, 
    [CallerFilePath] string filePath = null, 
    [CallerLineNumber] int lineNum = 0) 
{
    Console.WriteLine(
        $"{msg}, 呼叫端: {caller}, 檔案: {filePath}, 行號: {lineNum}");
}

執行結果:

發生錯誤, 呼叫端: Main, 檔案: Program.cs, 行號: 12

試試看:https://dotnetfiddle.net/wDYoVB


以上提及的 Caller* 特徵項皆隸屬於 System.Runtime.CompilerServices 命名空間。

Happy coding!

👉本文已同步發布於 GitHub 的 C# 學習筆記

沒有留言:

技術提供:Blogger.
回頂端⬆️