10

我尝试使用下面的代码创建自定义 .NET 属性,但不小心遗漏了子类。这产生了注释中显示的易于修复的编译器错误。

// results in compiler error CS0641: Attribute 'AttributeUsage' is 
// only valid on classes derived from System.Attribute
[AttributeUsage(AttributeTargets.Class)]
internal class ToolDeclarationAttribute
{
    internal ToolDeclarationAttribute()
    {
    }
}

我的问题是编译器如何知道该[AttributeUsage]属性只能应用于 的子类System.Attribute?使用 .NET Reflector 我看不到AttributeUsageAttribute类声明本身有什么特别之处。不幸的是,这可能只是编译器本身生成的一种特殊情况。

[Serializable, ComVisible(true), AttributeUsage(AttributeTargets.Class, Inherited=true)]
public sealed class AttributeUsageAttribute : Attribute
{
    ...

我希望能够指定我的自定义属性只能放在特定类(或接口)的子类上。这可能吗?

4

3 回答 3

27

我希望能够指定我的自定义属性只能放在特定类(或接口)的子类上。这可能吗?

实际上,有一种方法可以为子类(但不是接口)使用protected- 请参阅Restricting Attribute Usage。重现代码(但不是讨论):

abstract class MyBase {
    [AttributeUsage(AttributeTargets.Property)]
    protected sealed class SpecialAttribute : Attribute {}
}
class ShouldBeValid : MyBase {
    [Special] // works fine
    public int Foo { get; set; }
}
class ShouldBeInvalid { // not a subclass of MyBase
    [Special] // type or namespace not found
    [MyBase.Special] // inaccessible due to protection level
    public int Bar{ get; set; }
}
于 2009-07-27T21:32:28.053 回答
2

AttributeUsageAttribute只是一个魔术类(就像Attribute它本身一样)。这是一个内置的编译器规则,你不能为你自己的属性做类似的事情。

于 2009-07-27T21:17:44.887 回答
0

使用 ReSharper,您可以使用[JetBrains.Annotations.BaseTypeRequired(typeof(YouBaseType))]

于 2016-11-29T16:53:16.410 回答