【问题标题】:Custom actions in attribute's constructor属性构造函数中的自定义操作
【发布时间】:2014-08-26 11:24:53
【问题描述】:

我一直很好奇是否可以在不显式迭代程序集中定义的所有类型的情况下获得具有我自己的属性的所有类的列表。我试过的事情是让属性的构造函数将所有类型写入一个静态字段。由于未知原因,类型列表不包含单个条目。以下代码将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);
        }
    }
}

【问题讨论】:

  • 不,你必须迭代。属性是元数据,它们只有在您请求它们时才会实现(然后当您有实例时)。在您拥有 SmartAttribute 实例(使用 GetCustomAttribute())之前,它不会被创建(这就是原因,例如,您不能使用任何类型作为参数)。
  • @AdrianoRepetti 我尝试创建Test 的实例,但没有帮助。你的意思是只有当我打电话给GetCustomAttributes 时它们才会实现?对于严格(非惰性)语言来说,这是一种令人困惑的行为。
  • 是的。如果您编写new SmartAttribute(typeof(Test)),那么当然会调用构造函数,但[SmartAttribute(typeof(Test))] 对象在您明确要求其实例之前不存在。这既是因为性能(在需要之前不会构建对象,计算系统程序集上的属性,您会想象到影响),而且因为元数据也可以由非托管代码检查。
  • @AdrianoRepetti 您能否找到来自 C# 语言规范的引文作为答案,以便我可以结束这个问题?我一直试图自己找到它并迷路了。
  • 现在远离计算机,但快速搜索将我指向 C# 规范的第 17.3 节。它可能在那里。

标签: c# attributes


【解决方案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,了解有关检索用属性修饰的类型的更多讨论。

【讨论】:

  • 这正是我所做的,虽然对无数类型的迭代让我感到不安。
  • 是的,这似乎有点违反直觉。如果由于某种原因这对性能至关重要,您总是可以编写一个编译后步骤来进行分析和更新配置文件,这样代码只运行一次,而不是每次执行程序集时。
猜你喜欢
  • 2021-12-17
  • 1970-01-01
  • 2021-06-19
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多