我一直很好奇是否可以使用我自己的属性获取所有类的列表,而无需显式迭代程序集中定义的所有类型。我试过的是让属性的构造函数将所有类型写入静态字段。由于未知原因,类型列表不包含单个条目。以下代码将0
输出到控制台窗口。为什么呢?
[AttributeUsage(AttributeTargets.Class)]
class SmartAttribute : Attribute {
public static List<Type> Types = new List<Type>();
public SmartAttribute(Type type) {
Types.Add(type);
}
}
[SmartAttribute(typeof(Test))]
class Test {
}
class Program {
static void Main(string[] args) {
Console.WriteLine(SmartAttribute.Types.Count());
foreach (var type in SmartAttribute.Types) {
Console.WriteLine(type.Name);
}
}
}
答案 0 :(得分:1)
你想做的事是不可能的。属性是元数据,它们不是在运行时实例化的,因此不会调用构造函数。
如果你退后一步思考原因,那就有道理了。为了使您建议使用的代码,在执行任何代码之前运行时必须做的第一件事是创建所有属性的实例。然后你会遇到一些有趣的场景,如:
[AttributeB]
public class AttributeA : Attribute{}
[AttributeA]
public class AttributeB : Attribute {}
哪个构造函数会先行,何时知道停止等等?这就是为什么.Net架构师决定不执行属性构造函数的原因。
现在,要查找使用属性修饰的所有类型,您需要在Main
方法(或任何其他执行方法)中遍历程序集中的所有类型:
Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => Attribute.IsDefined(t, typeof(SmartAttribute)))
有关检索使用属性修饰的类型的更多讨论,请参阅get all types in assembly with custom attribute。