【问题标题】:Specify required base class for .NET attribute targets为 .NET 属性目标指定所需的基类
【发布时间】:2010-11-14 12:11:58
【问题描述】:

我尝试使用下面的代码创建自定义 .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
{
    ...

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

【问题讨论】:

  • 此限制有时表明您应该改用标记接口。它执行相同的功能,除非您需要将类级元数据作为参数传递。因此,如果实例可以很容易地提供一些东西的计数,那么接口可能需要一个公共属性来获取它。如果它必须是类级别的,那么你就会被 Attributes 困住。

标签: c# .net attributes custom-attributes


【解决方案1】:

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

实际上,有一种方法可以使用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; }
}

【讨论】:

  • 非常感谢!老实说,在遇到编译器错误之前我从未考虑过这样做,但我肯定会为您提供解决方案。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2015-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-12
      • 1970-01-01
      相关资源
      最近更新 更多