【发布时间】:2012-01-19 13:54:54
【问题描述】:
我最近阅读了有关属性和反射的文章,我认为在我的程序中包含元数据是一个好方法。我有这个抽象类,我希望从它继承的所有类都用类声明一些属性,因为我希望为我的程序创建自定义组件(那些派生类),并希望在运行时读取这些类的元数据。但是,派生类都必须显式声明我存储元数据的属性。那么如何在派生类中强制进行属性声明呢?谢谢。
【问题讨论】:
标签: c# inheritance reflection attributes
我最近阅读了有关属性和反射的文章,我认为在我的程序中包含元数据是一个好方法。我有这个抽象类,我希望从它继承的所有类都用类声明一些属性,因为我希望为我的程序创建自定义组件(那些派生类),并希望在运行时读取这些类的元数据。但是,派生类都必须显式声明我存储元数据的属性。那么如何在派生类中强制进行属性声明呢?谢谢。
【问题讨论】:
标签: c# inheritance reflection attributes
将您的属性类定义为自身具有AttributeUsageAttribute 属性,其中Inherited 属性为true。
或者不要,因为这是默认设置...
派生目标(即,如果属性在类上,则为类,如果在方法上,则为方法等)然后将继承该属性而无需显式声明。
【讨论】:
如果“强制”,你的意思是“编译时强制”:你不能。
【讨论】:
正如丹尼尔所说,你不能在编译时强制执行属性。
但是如果你想在运行时读取数据,为什么还要考虑属性和反射呢?你可以在你的抽象类中创建一个抽象方法:
abstract class Base
{
public abstract string Metadata();
}
class Derived1 : Base
{
public override string Metadata()
{
return "Metadata for Derived1";
}
}
class Derived2 : Base // won't compile, since Metadata has not been provided
{
}
当然,行为略有不同。使用此选项,您需要对派生类的 instance 的引用,而不仅仅是类型信息本身。另一方面,它避免了反射。
【讨论】:
正如丹尼尔所说,您不能在编译时强制执行。 您可以将属性添加到抽象父级并拾取它们。
另一种选择是添加一个方法来检查父类中是否存在属性,如果不存在则抛出异常。通过合适的方法调用它。
【讨论】:
由于类似的用例,遇到了这个老问题。在编译时强制使用属性的一种方法是编写一个分析器,类似于 xunit 框架所做的。这是一个例子: https://github.com/xunit/xunit.analyzers/blob/main/src/xunit.analyzers/TheoryMethodMustHaveTestData.cs
需要更多的努力,但确实有效。
【讨论】: