【发布时间】:2025-11-28 01:00:02
【问题描述】:
为了用AttributeUsage装饰一个类,被装饰的类也必须继承自Attribute。
我可以使用自定义属性强制执行类似的约束吗?
【问题讨论】:
标签: c# inheritance attributes constraints
为了用AttributeUsage装饰一个类,被装饰的类也必须继承自Attribute。
我可以使用自定义属性强制执行类似的约束吗?
【问题讨论】:
标签: c# inheritance attributes constraints
AttributeUsageAttribute 显然是该语言的核心功能,因此C# specification 强制执行此限制:
用
AttributeUsage属性修饰的类必须直接或间接派生自System.Attribute。否则,会发生编译时错误。
这意味着没有直接的方法可以实现这种限制。您可以编写自定义静态分析器以在错误使用时发出警告,或查看 Anton Anpilogov 的答案以了解解决方法。
【讨论】:
Contract.Requires(type.IsSubclassOf(typeof(Attribute))
这样做的唯一方法是使用受保护的属性,但在这种情况下,您将强制您的属性的用户从您的属性类继承。
abstract class CustomAttribute : Attribute {
[AttributeUsage(AttributeTargets.Class)]
protected sealed class MyTestAttribute : Attribute {}
}
[MyTest]
class DerivedFromYourCustomAttribute : CustomAttribute {
}
[MyTest]
class NotDerivedFromYourCustomAttribute {
}
【讨论】:
AttributeUsageAttribute 不是 System.Attribute 的嵌套类型,所以它留下了一个问题 - 该限制是如何执行的?
MyTestAttribute 限制为protected,但无法找到用该属性修饰的类型。我公开了MyTestAttribute,这样我就可以找到装饰类。
AttributeUsageAttribute 接受 C# 编译器的特殊处理。你不可以做这个。你可以看到它的源代码here。没有明显的特征。只有一个有趣的细节:AttributeUsageAttribute 应用于自身!
InternalGetCustomAttributes 方法的参数,与AttributeUsageAttribute 类无关。