情報属性を使用して、メソッドの呼び出し元に関する情報を取得します。 ソース コードのファイル パス、ソース コードの行番号、および呼び出し元のメンバー名を取得します。 メンバーの呼び出し元情報を取得するには、省略可能なパラメーターに適用される属性を使用します。 各省略可能なパラメーターは既定値を指定します。 次の表に、 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」 |
ファイナライザー | 文字列「Finalize」 |
ユーザー定義演算子または変換 | メンバーの生成された名前 (例: "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
引数に挿入されます。 開発者がnull
引数を使用してOperation
を呼び出すと、次のメッセージがArgumentException
に格納されます。
Argument failed validation: <func is not null>
この属性を使用すると、詳細を提供する診断ユーティリティを記述できます。 開発者は、必要な変更をより迅速に理解できます。 CallerArgumentExpressionAttributeを使用して、拡張メソッドのレシーバーとして使用された式を確認することもできます。 次のメソッドは、一定の間隔でシーケンスをサンプリングします。 シーケンスの要素数が頻度よりも少ない場合は、エラーが報告されます。
public static IEnumerable<T> Sample<T>(this IEnumerable<T> sequence, int frequency,
[CallerArgumentExpression(nameof(sequence))] string? message = null)
{
if (sequence.Count() < frequency)
throw new ArgumentException($"Expression doesn't have enough elements: {message}", nameof(sequence));
int i = 0;
foreach (T item in sequence)
{
if (i++ % frequency == 0)
yield return item;
}
}
前の例では、パラメーター sequence
に nameof
演算子を使用します。 この機能は C# 11 で使用できます。 C# 11 より前に、パラメーターの名前を文字列として入力する必要があります。 このメソッドは次のように呼び出します。
sample = Enumerable.Range(0, 10).Sample(100);
前の例では、メッセージが次のテキストである ArgumentException をスローします。
Expression doesn't have enough elements: Enumerable.Range(0, 10) (Parameter 'sequence')
こちらも参照ください
.NET