使用基于PostSharp的属性时缺少自定义属性

时间:2015-04-24 22:04:52

标签: custom-attributes postsharp

新手到PostSharp。请考虑以下代码:

using System;
using PostSharp.Aspects;

namespace PostSharp1 {

    [AttributeUsage(AttributeTargets.Property)][Serializable]public class Field1Attribute : System.Attribute { }
    [AttributeUsage(AttributeTargets.Property)][Serializable]public class Field2Attribute : LocationInterceptionAspect { }

    public class Person {
        [Field1][Field2]public string Name { get; set; }
    }

    class Program {

        static void Main(string[] args) {

            var Friend = new Person();
            Friend.Name = "Fred Bloggs";

            var Properties = Friend.GetType().GetProperties();
            Console.WriteLine("Properties: " + Properties.Length);
            var Count1 = 1;
            foreach (var Property in Properties) {
                var CustomAttributes = Property.GetCustomAttributes(false);
                Console.WriteLine("  Property #" + Count1++ + ": " + Property.Name + ", # custom attributes = " + CustomAttributes.Length);
                var Count2 = 1;
                foreach (System.Attribute CustomAttribute in CustomAttributes) {
                    Console.WriteLine("    Attribute #" + Count2++ + ": " + CustomAttribute.ToString());
                }
            }
        }

    }

}

使用Reflection在小Person类的属性上列出自定义属性的简化示例。

该程序列出了Field1Attribute(基于System.Attribute),但Field2Attribute似乎已被删除,因为它没有列出。

试图理解这里的机制以及为什么缺少LocationInterceptionAspect派生属性。

1 个答案:

答案 0 :(得分:2)

奇怪的是,有时候写这个问题可以让你研究答案。这是"按设计" - 应用后,将删除(从System.Attribute派生的)方面。有点意义,因为PostSharp真的是关于构建时间。但是,如文档中所述,可以防止它们被删除:

  

1.1.5。在运行时反映方面实例

     

属性多播主要被设计为一种向程序添加方面的机制。大多数情况下,在应用方面后,可以删除表示方面的自定义属性。默认情况下,如果你   向程序添加一个方面,并使用a查看生成的程序   反汇编程序或系统。反思,你不会发现这些   相应的自定义属性

     

如果您需要您的方面(或任何其他方面   要由System.Reflection或任何其他方式反映的多播属性   工具,你必须设置   MulticastAttributeUsageAttributePersistMetaData属性为true。对于   实例:

[MulticastAttributeUsage( MulticastTargets.Class, PersistMetaData = true )]
public class TagAttribute : MulticastAttribute
{
public string Tag;
}