透過資訊屬性,你可以獲得呼叫者的資料。 你可以取得原始碼的檔案路徑、原始碼中的行號,以及呼叫者的成員名稱。 要取得會員來電者資訊,請使用你套用於可選參數的屬性。 每個選擇性參數都會指定預設值。
C# 語言參考資料記錄了 C# 語言最新版本。 同時也包含即將推出語言版本公開預覽功能的初步文件。
文件中標示了語言最近三個版本或目前公開預覽版中首次引入的任何功能。
小提示
欲查詢某功能何時首次在 C# 中引入,請參閱 C# 語言版本歷史的條目。
下表列出命名空間中 System.Runtime.CompilerServices 定義的呼叫端資訊屬性:
| 屬性 | 說明 | 類型 |
|---|---|---|
| CallerFilePathAttribute | 包含呼叫端之原始程序檔的完整路徑。 完整路徑是在編譯時期的路徑。 | String |
| CallerLineNumberAttribute | 在來源檔案中呼叫方法的行號。 | Integer |
| CallerMemberNameAttribute | 呼叫者的方法名稱或屬性名稱。 | String |
| CallerArgumentExpressionAttribute | 自變數表達式的字串表示。 | String |
此資訊可協助您進行追蹤和偵錯,並協助您建立診斷工具。 下列範例示範如何使用呼叫端資訊屬性。 在方法的每個呼叫 TraceMessage 上,都會將自變數的呼叫端資訊插入至選擇性參數。
public void DoProcessing()
{
TraceMessage("Something happened.");
}
public void TraceMessage(string message,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
Trace.WriteLine("message: " + message);
Trace.WriteLine("member name: " + memberName);
Trace.WriteLine("source file path: " + sourceFilePath);
Trace.WriteLine("source line number: " + sourceLineNumber);
}
// Sample Output:
// message: Something happened.
// member name: DoProcessing
// source file path: c:\Visual Studio Projects\CallerInfoCS\CallerInfoCS\Form1.cs
// source line number: 31
您可以為每個選擇性參數指定明確的預設值。 你不能把來電者資訊屬性套用到非可選的參數上。 呼叫端資訊屬性不會讓參數成為選擇性。 相反地,它們會影響當參數被省略時傳入的預設值。 編譯器會在編譯時以文字形式將呼叫者資訊的值輸出到中介語言(IL)。 與例外屬性的結果 StackTrace 不同,混淆不會影響結果。 您可以明確提供選擇性自變數來控制呼叫端資訊,或隱藏呼叫端資訊。
成員名稱
使用屬性 CallerMemberName 以避免將成員名稱作為 String 被呼叫方法的參數指定。 藉由使用這項技術,您可以避免 重新命名重構 不會變更 String 值的問題。 這項優點特別適用於下列工作:
- 使用追蹤和診斷程序。
- 在綁定數據時實作INotifyPropertyChanged介面。 此介面允許物件的屬性通知綁定控制項該屬性變更。 控制件可以顯示更新的資訊。 若沒有
CallerMemberName屬性,您必須將屬性名稱指定為字面值。
下圖顯示當您使用 CallerMemberName 屬性時所傳回的成員名稱。
| 呼叫會發生在 內 | 成員名稱結果 |
|---|---|
| 方法、屬性或事件 | 呼叫的來源方法、屬性或事件名稱。 |
| 建構函式 | 字串 “.ctor” |
| 靜態建構函式 | 字串 “.cctor” |
| 終結器 | 字串「完成」 |
| 使用者定義的運算子或轉換 | 成員生成的名稱,例如「op_Addition」。 |
| 屬性建構函式 | 套用屬性之方法或屬性的名稱。 如果屬性是成員內的任何元素(例如參數、回傳值或一般型別參數),這個結果就是該元素所關聯的成員名稱。 |
| 不包含成員(例如,套用至型別的元件層級或屬性) | 選擇性參數的預設值。 |
自變數表達式
使用 當 System.Runtime.CompilerServices.CallerArgumentExpressionAttribute 你想傳遞表達式作為參數時。 診斷函式庫可以提供更多關於傳遞給參數的 表達 式細節。 除了參數名稱之外,藉由提供觸發診斷的表達式,開發人員還有觸發診斷之條件的詳細數據。 該額外資訊可讓您更輕鬆地修正。
下列範例示範如何在自變數無效時提供自變數的詳細資訊:
public static void ValidateArgument(string parameterName, bool condition, [CallerArgumentExpression("condition")] string? message=null)
{
if (!condition)
{
throw new ArgumentException($"Argument failed validation: <{message}>", parameterName);
}
}
你如以下範例所示呼叫:
public void Operation(Action func)
{
Utilities.ValidateArgument(nameof(func), func is not null);
func();
}
編譯器會將所用 condition 的表達式注入參數中 message 。 當開發人員使用 Operation 自變數呼叫 null 時,下列訊息會儲存在 中ArgumentException:
Argument failed validation: <func is not null>
利用此屬性,您可以撰寫診斷工具,提供更多細節。 開發人員可以更快速地瞭解需要哪些變更。 你也可以用 CallerArgumentExpressionAttribute 來判斷擴展成員接收器使用的表達式。 下列方法會定期取樣序列。 如果序列的元素少於頻率,則會報告錯誤:
extension<T>(IEnumerable<T> sequence)
{
public IEnumerable<T> Sample(int frequency,
[CallerArgumentExpression(nameof(sequence))] string? message = null)
{
if (sequence.Count() < frequency)
throw new InvalidOperationException($"Expression doesn't have enough elements: {message}");
int i = 0;
foreach (T item in sequence)
{
if (i++ % frequency == 0)
yield return item;
}
}
}
上述範例使用 nameof 參數 sequence的運算符。 您可以呼叫此方法,如下所示:
sample = Enumerable.Range(0, 10).Sample(100);
前述範例拋出 , ArgumentException 其訊息為以下文字:
Expression doesn't have enough elements: Enumerable.Range(0, 10) (Parameter 'sequence')