C# 特性(Attributes)详解

news/2025/1/18 2:41:57/

C# 特性(Attributes)详解

什么是特性?

特性(Attributes) 是 C# 提供的一种强大的元数据机制,用于在代码中添加描述性信息。它可以附加到程序的各种部分(类、方法、属性、字段等),供运行时或编译时使用。


常见用途

  1. 标注元数据
    • 为代码元素提供额外的信息。
    • 例如 [Obsolete] 特性提示某个方法已过时。
  1. 控制行为
    • 特性可以影响代码的执行逻辑或框架的行为。
    • 例如 [HttpGet] 告知 ASP.NET Core 这是一个 GET 请求的处理方法。
  1. 运行时反射
    • 通过反射获取特性的信息,动态改变程序逻辑。
    • 例如,通过 [Authorize] 特性决定用户是否有权限访问某功能。
  1. 编译器指令
    • 提供编译时的额外指令或警告信息。
    • 例如 [Conditional] 特性控制代码的条件编译。

如何定义和使用特性?

1. 内置特性

示例 1:[Obsolete]

标记某个方法或类为“已过时”。

csharp复制代码
public class Example
{[Obsolete("Use NewMethod instead.")]public void OldMethod(){Console.WriteLine("This is an old method.");}public void NewMethod(){Console.WriteLine("This is a new method.");}
}

使用时会提示编译警告:

csharp复制代码
var example = new Example();
example.OldMethod(); // 警告:Use NewMethod instead.

示例 2:[Serializable]

标记类为可序列化的类。

csharp复制代码
[Serializable]
public class Person
{public string Name { get; set; }public int Age { get; set; }
}

示例 3:[DllImport]

用于调用非托管代码(例如 DLL 文件)。

csharp复制代码
using System.Runtime.InteropServices;class Program
{[DllImport("user32.dll")]public static extern int MessageBox(int hWnd, string text, string caption, int type);static void Main(){MessageBox(0, "Hello, World!", "PInvoke Example", 0);}
}

2. 自定义特性

定义自定义特性

继承自 System.Attribute 类。

csharp复制代码
using System;[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class MyCustomAttribute : Attribute
{public string Description { get; }public MyCustomAttribute(string description){Description = description;}
}
使用自定义特性

将特性应用到类或方法。

csharp复制代码
[MyCustomAttribute("This is a test class.")]
public class TestClass
{[MyCustomAttribute("This is a test method.")]public void TestMethod(){Console.WriteLine("Test method executed.");}
}
读取特性信息(通过反射)

使用反射动态获取特性信息。

csharp复制代码
using System;
using System.Reflection;class Program
{static void Main(){var type = typeof(TestClass);var attributes = type.GetCustomAttributes<MyCustomAttribute>();foreach (var attr in attributes){Console.WriteLine($"Class Attribute: {attr.Description}");}var method = type.GetMethod("TestMethod");var methodAttributes = method.GetCustomAttributes<MyCustomAttribute>();foreach (var attr in methodAttributes){Console.WriteLine($"Method Attribute: {attr.Description}");}}
}

3. 特性参数

特性可以接受位置参数命名参数

csharp复制代码
[AttributeUsage(AttributeTargets.Method)]
public class LogAttribute : Attribute
{public string LogLevel { get; }public bool IsEnabled { get; set; }public LogAttribute(string logLevel){LogLevel = logLevel;}
}

使用特性时:

csharp复制代码
public class Demo
{[Log("Info", IsEnabled = true)]public void DoSomething(){Console.WriteLine("Doing something...");}
}

4. 常见内置特性

特性名称

说明

[Obsolete]

标记某方法或类为过时,提示开发者使用替代方案。

[Serializable]

指定类可以被序列化。

[NonSerialized]

用于字段,表示不参与序列化。

[Conditional]

控制条件编译,常用于调试日志等场景。

[DllImport]

用于声明调用非托管代码(PInvoke)。

[Flags]

标记枚举可以按位组合使用。

[DebuggerStepThrough]

告诉调试器跳过此代码段,不进入代码执行。

[TestMethod]

标记方法为单元测试方法(在 MSTest 框架中使用)。

[HttpGet]

, [HttpPost]

用于 ASP.NET Core 控制器方法,标记 HTTP 请求类型。


特性使用的高级场景

1. 控制序列化行为

通过特性控制类或字段在序列化中的表现。

csharp复制代码
[Serializable]
public class Employee
{public string Name { get; set; }[NonSerialized]public int TempData; // 不会被序列化
}

2. 条件编译

在某些场景下,控制代码是否编译或执行。

csharp复制代码
using System.Diagnostics;public class Example
{[Conditional("DEBUG")]public void LogDebugInfo(){Console.WriteLine("Debugging info...");}
}

3. ASP.NET Core 特性

在 ASP.NET Core 中,特性广泛用于控制路由、验证、授权等行为。

csharp复制代码
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{[HttpGet]public IEnumerable<string> Get(){return new string[] { "Sunny", "Rainy" };}
}

总结

  1. 特性是元数据:用于为代码添加描述性信息或控制行为。
  2. 易扩展性:可以通过自定义特性满足复杂需求。
  3. 结合反射:在运行时可以动态读取特性信息,适合灵活场景。
  4. 应用广泛:从简单的标记到复杂的框架行为控制,特性都能胜任。

http://www.ppmy.cn/news/1564041.html

相关文章

如何通过 Nginx 实现 CouchDB 集群的负载均衡并监控请求分发

在现代分布式系统中&#xff0c;负载均衡是确保高可用性和性能的关键组件。CouchDB 是一个强大的分布式数据库&#xff0c;而 Nginx 是一个高性能的反向代理和负载均衡器。本文将详细介绍如何通过 Nginx 实现 CouchDB 集群的负载均衡&#xff0c;并监控请求被分发到哪一台 Couc…

Nginx安全加固系列:404页面失去保护

为了预防危害漏洞&#xff0c; Nginx在配置文件里添加了一系列的标头&#xff0c;是通过add_head这个命令&#xff0c;常见的有 http {## 内容安全策略CSPadd_header Content-Security-Policy "default-src self; script-src self; "## 禁止该文件被frameadd_header…

Redis快速入门店铺营业状态设置

Redis简介 Redis是一种基于内存的键值对&#xff08;K-V&#xff09;数据库。 这意味着它与MySQL数据库类似&#xff0c;都能够用于存储数据&#xff0c;但两者又有着本质的区别。首先两者存储数据的结构不一样&#xff0c;Redis通过键&#xff08;key&#xff09;和值…

利用ffmpeg将视频转为m3u8并加密

参考链接 https://openatomworkshop.csdn.net/67457b7e3a01316874d8a2aa.html

销售团队如何选择销售业绩统计表模板?

在销售团队中&#xff0c;统计和分析业绩是日常工作的重要部分。比如&#xff0c;通过统计表&#xff0c;我们可以看到上个月各销售员的成交额&#xff0c;了解哪些产品受欢迎&#xff0c;哪些区域市场潜力大。这不仅帮助我们回顾过往表现&#xff0c;还能为未来决策提供依据。…

计算机网络 (40)域名系统DNS

前言 计算机网络域名系统DNS&#xff08;Domain Name System&#xff09;是互联网的基础技术之一&#xff0c;它负责将人类可读的域名转换为计算机用来通信的数字IP地址。 一、基本概念 DNS的主要目的是将域名解析或翻译为IP地址&#xff0c;使得用户可以通过简单易记的域名来访…

装饰器模式详解(附代码案例和源码分析)

目录 装饰器模式的本质 装饰器模式和继承结构的对比 源码中IO流的继承结构 具体装饰器类 装饰器的组合应用 装饰器链的特点 代码案例 定义coffee类型 coffee的实现类 装饰器抽象类 装饰器 - 季节限定 装饰器——加牛奶 装饰器——加糖 生成咖啡的简单工厂 咖…

饭搭难点亮点

文章目录 难点不同请求响应头设置解决跨域问题切换餐厅头像的更改 亮点组件复用懒加载mixins复用用户交互体验 难点 不同请求响应头设置 大部分的请求头都是’Content-Type’&#xff1a;‘application/json’ 但也有少数请求需要的是’multipart/form-data’&#xff0c;例如…