我有一个自定义属性,它应用于类属性和类本身。现在,必须应用我的自定义属性的所有类都派生自单个基类。
如何限制我的自定义属性,以便它只能应用于那些必须从我的基类派生的类?我该怎么做呢?
我有一个自定义属性,它应用于类属性和类本身。现在,必须应用我的自定义属性的所有类都派生自单个基类。
如何限制我的自定义属性,以便它只能应用于那些必须从我的基类派生的类?我该怎么做呢?
Darn,当我证明自己错了时,我讨厌它...如果你将属性定义为a,它就可以了 保护 基类的嵌套类型:
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; }
}
(原始答案)
你不能这样做 - 至少,不是在编译时。
属性可以被限制(例如)“class”,“struct”,“method”,“field”等等 - 但不能更精细。
当然,由于属性本身不做任何事情(忽略PostSharp),它们对其他类型是惰性的(并且对你的类型不敏感,除非你在运行时添加一些代码来查看属性)。
你可以写一个FxCop规则,但这似乎有点过分。
不过,我想知道属性是否是最佳选择:
现在,必须应用我的自定义属性的所有类都派生自单个基类。
如果他们 必须 应用您的自定义属性,也许是 abstract
(或者只是 virtual
)属性/方法会是更好的选择吗?
abstract class MyBase {
protected abstract string GetSomeMagicValue {get;}
}
class MyActualType : MyBase {
protected override string GetSomeMagicValue {get {return "Foo";}}
}
我不知道有任何方法可以使用自定义属性。
更好的方法是让类实现具有泛型约束的接口
所以
class MyAttribute
{
// put whatever custom data you want in here
}
interface IAttributeService<T> where T : MyBaseClass
{
MyAttribute Value{get;}
}
然后你的基类会这样做
class MyBaseClass : IAttributeService<MyBaseClass>
{
private MyAttribute m_attrib;
IAttributeService<MyClass>.Value
{
get {return m_attrib;}
}
}
这样编译器将在编译时强制执行约束,以便只有类
派生自MyBaseClass可以实现该接口。
我通过定义一个MyAttribute类使其相当可扩展,但是如果你需要更简单的东西,你当然可以返回一个字符串或一个bool
我还将MyAttribute成员设为私有,以便派生类无法看到它并更改它但可以使其受到保护并允许派生类访问(如果您愿意)。