1

我正在尝试做一些我认为应该直截了当且简单易行的事情,但就我的一生而言,我无法让它发挥作用。使用 PostSharp,我想创建一个应用于类(或接口)定义的方面,并且该方面在编译时反映它已应用于的类型,然后将该反射信息存储在一个变量中,以便在运行。

我知道应该使用 CompileTimeInitialize 函数来生成反射信息并将其保存到变量中。然后这一切都被序列化了。但是,我无法在运行时获取存储的信息。RuntimeInitialize 可以看到变量和其中的数据,但是当我使用 GetCustomAttributes 从代码中其他位置的类型获取属性时,该属性为空。

这是我到目前为止的一些代码:

[Serializable]
[MulticastAttributeUsage(MulticastTargets.Class, AllowMultiple = false, PersistMetaData = true)]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class MetadataAttribute : TypeLevelAspect {

    public MetadataAttribute() { }

    private int test;

    public override bool CompileTimeValidate(Type type) {
        this.test = 11;
        return true;
    }

    public override void CompileTimeInitialize(Type type, AspectInfo aspectInfo) {
        this.test = 9;
    }

    public override void RuntimeInitialize(Type type) {
        // When I break here, I can see during debugging, that test is 11 (I would have expected 9 to be honest, but I suspect that CompileTimeInitialize is not executed for a TypeLevelAspect - unless I am mistaken?)            
    }

}

这是我试图用来提取数字的控制台应用程序:

class Program {
    static void Main(string[] args) {
        var ma = typeof(Test).GetCustomAttribute<MetadataAttribute>();
        var test = new Test();
        var ma2 = test.GetType().GetCustomAttribute<MetadataAttribute>();
        // When I break here, both ma and ma2 have test set to 0.
    }
}

[Metadata]
public class Test { }

在此先感谢您的帮助,非常感谢,并且让我的头发在头上的寿命比在我手中的时间长:)

4

1 回答 1

1

当您使用Type.GetCustomAttributes时,您需要 CLR 从存储在元数据中的自定义属性的定义构建一个新实例,即通过调用构造函数并设置字段和属性。因此,您获得的不是 PostSharp 创建和初始化的实例,而是一个全新的实例。

如果您想访问 PostSharp 实例,您应该使用RuntimeInitialize将此实例存储在方面实例的某种共享存储库中,然后从代码中访问它们。请注意,PostSharpRuntimeInitialize延迟运行,因此在初始化之前您将无法访问您的实例。

于 2013-01-30T07:18:37.517 回答