C#如何实现自定义Attribute(特性)?元数据编程在C#中的高级应用

来源:这里教程网 时间:2026-02-21 17:31:46 作者:

在C#中,自定义Attribute(特性)是一种强大的元数据编程手段,允许开发者将声明性信息附加到代码元素上,如类、方法、属性等。这些信息可以在运行时通过反射读取并执行相应逻辑,广泛应用于序列化、权限验证、日志记录、AOP(面向切面编程)等场景。

如何定义自定义Attribute

要创建一个自定义特性,需要定义一个继承自System.Attribute的类。命名惯例是将类名以“Attribute”结尾,但在使用时可以省略该后缀。

示例:定义一个用于标记需要权限验证的方法特性

public class RequirePermissionAttribute : Attribute
{
    public string Permission { get; }
    public RequirePermissionAttribute(string permission)
    {
        Permission = permission;
    }
}

这个特性只能用于方法,但默认情况下它可以应用于任何程序元素。为了限制使用范围,可以使用AttributeUsage特性进行约束。

控制特性的应用目标和行为

通过AttributeUsage指定特性可应用的目标元素类型、是否允许多次使用以及是否继承到派生类。

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequirePermissionAttribute : Attribute
{
    public string Permission { get; }
    public RequirePermissionAttribute(string permission)
    {
        Permission = permission;
    }
}

AttributeTargets.Method 表示只能用在方法上 AllowMultiple = false 禁止同一个元素重复添加该特性 Inherited = true 允许派生类继承基类上的特性

在运行时通过反射读取特性信息

定义完特性后,可在运行时通过反射检查某个成员是否被标记,并获取其数据,从而决定程序行为。

示例:检查方法是否需要特定权限

public static bool HasPermissionRequirement(MethodInfo method, string requiredPermission)
{
    var attr = method.GetCustomAttribute<RequirePermissionAttribute>();
    return attr != null && attr.Permission == requiredPermission;
}

使用方式:

public class OrderService
{
    [RequirePermission("ManageOrders")]
    public void DeleteOrder(int orderId)
    {
        // 删除订单逻辑
    }
}
// 调用时检查权限
var method = typeof(OrderService).GetMethod("DeleteOrder");
if (HasPermissionRequirement(method, "ManageOrders"))
{
    Console.WriteLine("该方法需要 ManageOrders 权限");
}

高级应用场景:结合AOP实现拦截逻辑

虽然C#本身不直接支持方法拦截,但结合特性与动态代理(如Castle DynamicProxy)或源生成器(Source Generator),可以实现类似AOP的功能。

例如,在ASP.NET Core中,AuthorizeAttribute就是典型的自定义特性应用——控制器或动作方法被打上该特性后,请求会先经过授权中间件验证。

你也可以设计一个日志特性:

public class LogExecutionTimeAttribute : Attribute { }

配合依赖注入和拦截机制,在方法执行前后自动记录耗时(需借助第三方库或编译期工具)。

基本上就这些。自定义Attribute + 反射构成了C#元数据驱动编程的核心,合理使用能让代码更清晰、扩展性更强。关键在于把横切关注点(如权限、日志、验证)从主业务逻辑中解耦出来,提升可维护性。

相关推荐

热文推荐