C# 中使用调用者信息特性简化代码[通俗易懂]

C# 中使用调用者信息特性简化代码[通俗易懂]在 C# 中,有四个比较实用的调用者信息特性(Caller Info Attributes),可以应用于可选的方法参数上。在调用方法时若不明确提

大家好,欢迎来到IT知识分享网。

在 C# 中,有四个比较实用的调用者信息特性(Caller Info Attributes),可以应用于可选的方法参数上。在调用方法时若不明确提供参数,则自动将相关调用者信息赋给参数。

调用者源码路径 [CallerFilePath]

[CallerFilePath] 可以将调用者源码所在的路径赋值给相关参数。

 // Program.cs
 
 using System.Runtime.CompilerServices;
 
 void CallerFilePath([CallerFilePath] string? message = null)
 {
     Console.WriteLine(message);
 }
 
 CallerFilePath();

IT知识分享网

上述代码会在控制台输出 Program.cs 文件的路径:d:\CSharpStudy\Attribute\Program.cs (输出结果为笔者代码的路径,根据文件路径的不同结果会有所不同)。

调用者行号 [CallerLineNumber]

[CallerLineNumber] 特性将调用者在源码中的行号赋值给相关参数。

IT知识分享网 using AttributeStudy;
 using System.Runtime.CompilerServices;
 
 
 void CallerLineNumber([CallerLineNumber] int? lineNumber = null)
 {
     Console.WriteLine(lineNumber);
 }
 
 CallerLineNumber();

上述代码会在控制台输出 10 ,因为调用者在源码中为第10行。[CallerLineNumber][CallerFilePath] 的主要应用场景是调试和记录日志。

调用者名称 [CallerMemberName]

[CallerMemberName] 特性将调用者名称信息赋值给相关参数。名称在代码中用途很广泛,因此 [CallerMemberName] 的使用频次比 [CallerLineNumber][CallerFilePath] 广,在某些特定场景下,能够极大简化代码,最常见的是我们熟知的,在 MVVM 数据绑定中高频使用的 NotifyPropertyChanged 模式。

 public class Person : INotifyPropertyChanged
 {
     public event PropertyChangedEventHandler? PropertyChanged;
 
     void RaisePropertyChanged([CallerMemberName] string? propertyName = null)
         => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 
     string _name = string.Empty;
     public string Name
     {
         get => _name;
         set
         {
             if (value != _name)
             {
                 _name = value;
                 // 无需显示指定调用者名称
                 // 编译器自动赋值
                 RaisePropertyChanged();
             }
         }
     }
 }

在上述代码中,RaisePropertyChanged 方法的可选参数 propertyName 应用了 [CallerMemberName] 特性,因此调用时如果特殊需求,不必每次显示指定调用者名称,由编译器自动将调用者名称赋值给 propertyName ,简洁优雅,尤其是在属性非常多时非常有用。

调用参数表达式 [CallerArgumentExpression]

[CallerArgumentExpression] 是一个非常新的特性,在 C# 10 中方才引入,可以将调用参数表达式赋值给相关参数。

IT知识分享网 void CallerArgumentExpression(int number, [CallerArgumentExpression("number")] string? expression = null)
 {
     Console.WriteLine(expression);
 }
 
 CallerArgumentExpression(3 * 3);

上述代码会在控制台输出 3 * 3。实际上,咋编译时,编译器直接把调用 number 的表达式赋给了 expression 参数,如果有注释,也原样包含。

上面代码中的 CallerArgumentExpression(3 * 3) 相当于 CallerArgumentExpression(3 * 3,” 3 * 3″ )。如果表达式中包含注释,同样也会输出。

 void CallerArgumentExpression(int number, [CallerArgumentExpression("number")] string? expression = null)
 {
     Console.WriteLine(expression);
 }
 
 CallerArgumentExpression(3 * /* Comment */ 3);

上述代码会输出 3 * /* Comment */ 3

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/6767.html

(0)
上一篇 2022-12-20 18:30
下一篇 2022-12-20 18:50

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信