【.NET Core】你认识Attribute之CallerMemberName、CallerFilePath、CallerLineNumber三兄弟

简介: 【.NET Core】你认识Attribute之CallerMemberName、CallerFilePath、CallerLineNumber三兄弟


一、概述

CallerMemberName、CallerFilePath、CallerLineNumber特性

CallerMemberName:调用方法的名称。

CallerFilePath:调用方法的所有的类文件绝对地址。

CallerLineNumber:调用方法所在行号,可以用来记录日志,能够获取记录日志所在的行号和方法及调用文件。


二、CallerMemberNameAttribute类

允许获取方式调用方的方法或属性名称。

将CallerMemberName属性应用于具有默认值的可选参数。必须为可选参数指定显示默认值。不能将此属性应用于未指定为可选参数。


可以使用CallerMemberName特性来避免将成员名称指定为所调用的方法的String参数。通过使用这种技术,可以避免"重命名重构"不更改String值的问题。这对于以下任务特别有用:


  • 使用跟踪和诊断例程
  • 在绑定数据时实现INotifyPropertyChanged接口。此接口允许对象的属性通知绑定控件该属性已更改,以便此控件能够显示更新的信息。 如果没有 CallerMemberName 特性,则必须将属性名称指定为文本。


三、CallerFilePathAttribute 类

允许获取包含调用方法的源文件的完整路径。这是编译时的文件路径

将特性应用于CallerFilePath具有默认值的可选参数。必须为可选参数指定显示默认值。不能将此属性应用于未指定为可选参数。


四、CallerLineNumberAttribute 类

允许获取源文件中调用方法的行号。

CallerLineNumber 属性应用于具有默认值的可选参数。 必须为可选参数指定显式默认值。 不能将此属性应用于未指定为可选参数。


五、使用示例

pubpublic void DoProcessing()
{
    TraceMessage("Something happened.");
}

public void TraceMessage(string message,
        [System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
        [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
        [System.Runtime.CompilerServices.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);
}


六、使用场景

6.1/可用于日志的记录


pubpublic class LogHelp
{
        public static void Info(
              string message,
          [CallerMemberName] string memberName = "",
          [CallerFilePath] string sourceFilePath = "",
          [CallerLineNumber] int sourceLineNumber = 0)
        {
            Console.WriteLine("信息为: " + message);
            Console.WriteLine("方法名称: " + memberName);
            Console.WriteLine("源文件地址: " + sourceFilePath);
            Console.WriteLine("方法使用所在行号: " + sourceLineNumber);
        }
 
        public static void Debug(
              string message,
          [CallerMemberName] string memberName = "",
          [CallerFilePath] string sourceFilePath = "",
          [CallerLineNumber] int sourceLineNumber = 0)
        {
            Console.WriteLine("信息为: " + message);
            Console.WriteLine("方法名称: " + memberName);
            Console.WriteLine("源文件地址: " + sourceFilePath);
            Console.WriteLine("方法使用所在行号: " + sourceLineNumber);
        }
 
        public static void Error(
             Exception ex,
         [CallerMemberName] string memberName = "",
         [CallerFilePath] string sourceFilePath = "",
         [CallerLineNumber] int sourceLineNumber = 0)
        {
            Console.WriteLine("信息为: " + ex.Message);
            Console.WriteLine("方法名称: " + memberName);
            Console.WriteLine("源文件地址: " + sourceFilePath);
            Console.WriteLine("方法使用所在行号: " + sourceLineNumber);
        }
 
}

6.2/CallerMemberName简化InotifyPropertyChange的实现

WPF中,当我们要使用MVVM的方式绑定一个普通对象的属性时,界面上往往需要获取到属性变更的通知。一般我们会新建一个类,并继承InotifyPropertyChange接口。


class NotifyObject : INotifyPropertyChanged
{
    private int number;
    public int Number
    {
        get { return number; }
        set { number = value; OnPropertyChanged("Number"); }
    }
 
    private string text;
    public string Text
    {
        get { return text; }
        set { text = value; OnPropertyChanged("Text"); }
    }

 
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName = "")
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}


这么做有一个比较大的隐患,那就是用了字符串的硬编码的方式传递了属性名称,一旦拼写错误或因为重构代码忘记去更新这个字符串时,这样就会导致界面上得不到更新。

硬编码的方式来保证两者的一致性是不靠谱的行为

可以是使用InotifyPropertyChange实现


class NotifyObject : INotifyPropertyChanged
{
     private int number;
     public int Number
     {
        get { return number; }
        set { number = value; OnPropertyChanged(); }
     }

     private string text;
     public string Text
     {
        get { return text; }
        set { text = value; OnPropertyChanged(); }
     }
 
 
     public event PropertyChangedEventHandler PropertyChanged;
     protected void OnPropertyChanged([CallerMemberName]string propertyName = "")
     {
         PropertyChangedEventHandler handler = PropertyChanged;
         if (handler != null)
         {
            handler(this, new PropertyChangedEventArgs(propertyName));
         }
     }
}

在新的OnpertyChangeEventHandler,用[CallerMemberName]属性修饰参数,那么在某个属性发生改变时,会调用此函数,propertyName就有了该属性的名字,因此实现前面相同的功能,但我们不需要显示传入属性名了。

目录
相关文章
|
10天前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:<https://github.com/khellang/Scrutor>
32 5
|
2月前
|
存储 开发框架 JSON
ASP.NET Core OData 9 正式发布
【10月更文挑战第8天】Microsoft 在 2024 年 8 月 30 日宣布推出 ASP.NET Core OData 9,此版本与 .NET 8 的 OData 库保持一致,改进了数据编码以符合 OData 规范,并放弃了对旧版 .NET Framework 的支持,仅支持 .NET 8 及更高版本。新版本引入了更快的 JSON 编写器 `System.Text.UTF8JsonWriter`,优化了内存使用和序列化速度。
|
28天前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
38 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
18天前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
24 3
|
2月前
|
存储 编译器
.Net特性Attribute的高级使用
【10月更文挑战第14天】在.NET中,特性(Attribute)是一种强大的机制,用于在代码中添加元数据。本文介绍了特性的高级用法,包括自定义特性、通过反射读取特性、条件编译与特性结合、多个特性应用以及特性继承。通过示例展示了如何创建自定义特性类、应用自定义特性,并通过反射获取特性信息。此外,还介绍了如何利用条件编译符号实现不同版本的代码控制,以及如何在一个代码元素上应用多个特性。最后,探讨了如何通过`AttributeUsage`控制特性的继承行为。
|
3月前
|
开发框架 监控 前端开发
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
|
3月前
|
开发框架 .NET 中间件
ASP.NET Core Web 开发浅谈
本文介绍ASP.NET Core,一个轻量级、开源的跨平台框架,专为构建高性能Web应用设计。通过简单步骤,你将学会创建首个Web应用。文章还深入探讨了路由配置、依赖注入及安全性配置等常见问题,并提供了实用示例代码以助于理解与避免错误,帮助开发者更好地掌握ASP.NET Core的核心概念。
111 3
|
2月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
|
3月前
|
开发框架 NoSQL .NET
利用分布式锁在ASP.NET Core中实现防抖
【9月更文挑战第5天】在 ASP.NET Core 中,可通过分布式锁实现防抖功能,仅处理连续相同请求中的首个请求,其余请求返回 204 No Content,直至锁释放。具体步骤包括:安装分布式锁库如 `StackExchange.Redis`;创建分布式锁服务接口及其实现;构建防抖中间件;并在 `Startup.cs` 中注册相关服务和中间件。这一机制有效避免了短时间内重复操作的问题。
|
4月前
|
开发框架 监控 .NET
开发者的革新利器:ASP.NET Core实战指南,构建未来Web应用的高效之道
【8月更文挑战第28天】本文探讨了如何利用ASP.NET Core构建高效、可扩展的Web应用。ASP.NET Core是一个开源、跨平台的框架,具有依赖注入、配置管理等特性。文章详细介绍了项目结构规划、依赖注入配置、中间件使用及性能优化方法,并讨论了安全性、可扩展性以及容器化的重要性。通过这些技术要点,开发者能够快速构建出符合现代Web应用需求的应用程序。
70 0