前言
上次,我们《使用 CallerArgumentExpression 检查弃元参数》,它实际是利用编译器编译时将变量名称传入。
其实,.NET中提供了多个[Caller*]属性,帮助我们轻松获取调用者信息。.
CallerFilePathAttribute
允许获取包含调用方的源文件的完整路径。
FilePath();
static void FilePath([CallerFilePath] string filepath = "")
{
Console.WriteLine(filepath);
}
CallerMemberNameAttribute
允许获取方法调用方的方法或属性名称。
public void DoProcessing()
{
MemberName();
}
static void MemberName([CallerMemberName] string name = "")
{
Console.WriteLine(name);
}
//输出
DoProcessing
CallerLineNumberAttribute
允许获取源文件中调用方法的行号。
LineNumber();
static void LineNumber([CallerLineNumber] int lineNumber = 0)
{
Console.WriteLine(lineNumber);
}
CallerArgumentExpressionAttribute
允许捕获传递给方法的表达式。
ThrowIfOutOfRange(age <= 0);
static void ThrowIfOutOfRange(bool argument, [CallerArgumentExpression("argument")] string? paramName = null)
{
if (argument)
throw new ArgumentOutOfRangeException(paramName);
}
![.NET中神奇的[Caller*]属性](/file/202203/2022031622395632.jpg)
结论
你可以在任何方法中将这些[Caller*]属性作为可选参数,最佳做法是将参数添加到方法的末尾:
public void TraceMessage(string message,
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
System.Diagnostics.Trace.WriteLine("message: " + message);
System.Diagnostics.Trace.WriteLine("member name: " + memberName);
System.Diagnostics.Trace.WriteLine("source file path: " + sourceFilePath);
System.Diagnostics.Trace.WriteLine("source line number: " + sourceLineNumber);
}
反编译代码,发现编译器会把代码编译成如下形式
TraceMessage("Hello My IO!");