Inheritance 限制自定义属性,使其只能应用于C#中的特定类型?

Inheritance 限制自定义属性,使其只能应用于C#中的特定类型?,inheritance,attributes,c#-2.0,Inheritance,Attributes,C# 2.0,我有一个自定义属性,它应用于类属性和类本身。现在,所有必须应用自定义属性的类都是从单个基类派生的 如何限制自定义属性,使其仅应用于那些必须从基类派生的类?我该怎么做?该死,我讨厌证明自己错了。。。如果将属性定义为基类的受保护的嵌套类型,则该选项有效: abstract class MyBase { [AttributeUsage(AttributeTargets.Property)] protected sealed class SpecialAttribute : Attrib

我有一个自定义属性,它应用于类属性和类本身。现在,所有必须应用自定义属性的类都是从单个基类派生的


如何限制自定义属性,使其仅应用于那些必须从基类派生的类?我该怎么做?

该死,我讨厌证明自己错了。。。如果将属性定义为基类的受保护的嵌套类型,则该选项有效:

abstract class MyBase {
    [AttributeUsage(AttributeTargets.Property)]
    protected sealed class SpecialAttribute : Attribute {}
}

class ShouldBeValid : MyBase {
    [Special]
    public int Foo { get; set; }
}
class ShouldBeInvalid {
    [Special] // type or namespace not found
    [MyBase.Special] // inaccessible due to protection level
    public int Bar{ get; set; }
}

(原答覆)

您不能这样做-至少在编译时不能这样做

属性(对于exmaple)可以限制为“类”、“结构”、“方法”、“字段”等,但不能更细粒度

当然,由于属性本身不起任何作用(忽略PostSharp),因此它们在其他类型上是惰性的(在您的类型上也是惰性的,除非您在运行时添加一些代码来查看属性)

你可以写一个FxCop规则,但这似乎太过分了

但是,我想知道属性是否是最佳选择:

现在,所有必须应用自定义属性的类都是从单个基类派生的

如果他们必须应用您的自定义属性,那么
抽象属性(或者只是
虚拟属性/方法)可能是更好的选择

abstract class MyBase {
    protected abstract string GetSomeMagicValue {get;}
}
class MyActualType : MyBase {
    protected override string GetSomeMagicValue {get {return "Foo";}}
}

我不知道如何使用自定义属性执行此操作。
更好的方法是让类实现具有泛型约束的接口

所以

class属性
{
//在这里输入您想要的任何自定义数据
}
接口IAttributeService,其中T:MyBaseClass
{
MyAttribute值{get;}
}
那么你的基类会这么做

class MyBaseClass : IAttributeService<MyBaseClass>
{
     private MyAttribute m_attrib;

     IAttributeService<MyClass>.Value
     {
         get {return m_attrib;}
     }
}
class MyBaseClass:IAttributeService
{
私有属性m_attrib;
IAttributeService.Value
{
获取{return m_attrib;}
}
}
这样,编译器将在编译时强制执行该约束,以便只有类
从MyBaseClass派生的可以实现接口。
我通过定义MyAttribute类使其具有相当的可扩展性,但如果需要更简单的东西,当然可以只返回字符串或bool


我还将MyAttribute成员设置为私有,以便派生类无法查看和更改它,但可以将其设置为受保护的,并允许派生类访问(如果需要)。

您想强制它(以便自动完成)还是限制它(以便它不能应用于其他类型)?我想限制它,使它不能应用于非从我的基类派生的类型以外的类型。编辑:该死,我想我找到了一种方法来做这件事,这自相矛盾!给我一个新的…谢谢马克。我正在将属性应用于属性以进行映射。基类具有一个方法,该方法返回已应用此属性的派生类中的所有属性。此外,允许一个属性应用于任何类型或成员而没有任何意义,甚至在我得出任何结论之前,我也没有找到任何这样做的文档,我想给它一个stackoverflow的机会。我相信属性是有目的地应用的,那么为什么允许它应用于那些没有目的的类型或成员呢。没有任何机制可以禁止它。我觉得这很有趣,可以在博客上写下来:@Marc:谢谢你,马克,你太棒了。我在设计和实现自己的紧凑型ORM时遇到了这种需求。我几乎完成了我的工作,并希望将属性的使用限制为仅从EntityBase类派生的类。
class MyBaseClass : IAttributeService<MyBaseClass>
{
     private MyAttribute m_attrib;

     IAttributeService<MyClass>.Value
     {
         get {return m_attrib;}
     }
}