方案: 我有一个基类“MyBase”。 我有一个自定义属性“MyAttrib”
我这样做:
[MyAttrib(1234)]
class MyClass : MyBase()
{
MyClass()
{
}
}
问题: 我能否以任何方式强制从MyBase中获取属性MyAttrib?
答案 0 :(得分:26)
不,编译器无法在C#中使用属性。您还有其他一些选择。您可以编写一个单元测试来反映程序集中的所有类型并检查属性。但不幸的是,没有办法让编译器强制使用属性。
答案 1 :(得分:2)
你可以使用PostSharp。 从OnMethodInvocationAspect类(PostSharp)继承您的属性类,并覆盖CompileTimeValidate方法。
有点类似;虽然相反(我只希望某个属性可以应用于实现特定接口的类): http://fgheysels.blogspot.com/2008/08/locking-system-with-aspect-oriented.html答案 2 :(得分:2)
我所做的是在MyBase
类中有一个抽象属性或方法,因此继承类被强制覆盖(并因此实现)此属性/方法。
不像属性那样干净,但比我认为在运行时检查要好。
答案 3 :(得分:0)
如果要确保基类型或接口的所有类都具有属性,可以添加一个简单的单元测试,该测试获取所有派生类并断言它们各自具有该属性并添加单元测试的结果进入你的进一步构建过程。
答案 4 :(得分:0)
我想象的不再与原始海报相关,但是对于像我这样好奇的人,这是可行的。
以下方法有效,但遗憾的是,这不是编译时检查,因此,我不能诚实地推荐使用它。对于大多数事情,您最好使用接口,虚拟和抽象。
必填属性:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class RequiredRandomThingAttribute : Attribute { /* ... */ }
派生类需要它的父类:
public class ParentRequiringAttribute
{
public ParentRequiringAttribute()
{
if (this.GetType().GetCustomAttributes(typeof(RequiredRandomThingAttribute), false).Length == 0)
throw new NotImplementedException(this.GetType().ToString());
}
}
并确认一切正常:
[RequiredRandomThing()]
public class CompleteSubclass : ParentRequiringAttribute { /* ... */ }
public class IncompleteSubclass : ParentRequiringAttribute { /* ... */ }
static public int Main(string[] args)
{
var test1 = new CompleteSubclass();
var test2 = new IncompleteSubclass(); // throws
}
改进验证应该相当容易,但是我自己的调查到此为止。