這篇筆記要整理的是 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 不是真的!
這裡不妨順便複習一下其他 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
以上提及的 Caller* 特徵項皆隸屬於 System.Runtime.CompilerServices
命名空間。
Happy coding!
👉本文已同步發布於 GitHub 的 C# 學習筆記
沒有留言: