정보 특성을 사용하여 메서드에 대한 호출자에 대한 정보를 가져옵니다. 소스 코드의 파일 경로, 소스 코드의 줄 번호 및 호출자의 멤버 이름을 가져옵니다. 멤버 호출자 정보를 얻으려면 선택적 매개 변수에 적용되는 특성을 사용합니다. 각 선택적 매개 변수는 기본값을 지정합니다. 다음 표에서는 네임스페이스에 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(Intermediate Language)에 리터럴로 내보내집니다. 예외에 대한 속성의 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 . 개발자가 인수를 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 메시지를 throw합니다.
Expression doesn't have enough elements: Enumerable.Range(0, 10) (Parameter 'sequence')
참고하십시오
.NET