CustomAttributeData 类

定义

提供对加载到仅反射上下文的程序集、模块、类型、成员和参数的自定义属性数据的访问权限。

C#
public class CustomAttributeData
C#
[System.Runtime.InteropServices.ComVisible(true)]
[System.Serializable]
public sealed class CustomAttributeData
C#
[System.Runtime.InteropServices.ComVisible(true)]
[System.Serializable]
public class CustomAttributeData
继承
CustomAttributeData
属性

示例

以下示例定义了一个具有四个构造函数和四个属性的自定义属性。 其中两个属性是只读的,使用构造函数的位置参数进行设置。 其他两个属性是可读/写的,只能使用命名参数进行设置。 一个位置属性是字符串数组,一个命名属性是整数数组。

该特性可应用于程序集、在该程序集中声明的类型、该类型的方法以及该方法的参数。 这些情况使用不同的构造函数。 执行时,程序集将自身加载到仅限反射的上下文中,并显示有关应用于它的自定义属性及其包含的类型和成员的信息。

应用于 类型的属性演示具有位置参数和命名参数的数组属性。

C#
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Collections.ObjectModel;

// The example attribute is applied to the assembly.
[assembly:Example(ExampleKind.ThirdKind, Note="This is a note on the assembly.")]

// An enumeration used by the ExampleAttribute class.
public enum ExampleKind
{
    FirstKind,
    SecondKind,
    ThirdKind,
    FourthKind
};

// An example attribute. The attribute can be applied to all
// targets, from assemblies to parameters.
//
[AttributeUsage(AttributeTargets.All)]
public class ExampleAttribute : Attribute
{
    // Data for properties.
    private ExampleKind kindValue;
    private string noteValue;
    private string[] arrayStrings;
    private int[] arrayNumbers;

    // Constructors. The parameterless constructor (.ctor) calls
    // the constructor that specifies ExampleKind and an array of
    // strings, and supplies the default values.
    //
    public ExampleAttribute(ExampleKind initKind, string[] initStrings)
    {
        kindValue = initKind;
        arrayStrings = initStrings;
    }
    public ExampleAttribute(ExampleKind initKind) : this(initKind, null) {}
    public ExampleAttribute() : this(ExampleKind.FirstKind, null) {}

    // Properties. The Note and Numbers properties must be read/write, so they
    // can be used as named parameters.
    //
    public ExampleKind Kind { get { return kindValue; }}
    public string[] Strings { get { return arrayStrings; }}
    public string Note
    {
        get { return noteValue; }
        set { noteValue = value; }
    }
    public int[] Numbers
    {
        get { return arrayNumbers; }
        set { arrayNumbers = value; }
    }
}

// The example attribute is applied to the test class.
//
[Example(ExampleKind.SecondKind,
         new string[] { "String array argument, line 1",
                        "String array argument, line 2",
                        "String array argument, line 3" },
         Note="This is a note on the class.",
         Numbers = new int[] { 53, 57, 59 })]
public class Test
{
    // The example attribute is applied to a method, using the
    // parameterless constructor and supplying a named argument.
    // The attribute is also applied to the method parameter.
    //
    [Example(Note="This is a note on a method.")]
    public void TestMethod([Example] object arg) { }

    // Main() gets objects representing the assembly, the test
    // type, the test method, and the method parameter. Custom
    // attribute data is displayed for each of these.
    //
    public static void Main()
    {
        Assembly asm = Assembly.ReflectionOnlyLoad("Source");
        Type t = asm.GetType("Test");
        MethodInfo m = t.GetMethod("TestMethod");
        ParameterInfo[] p = m.GetParameters();

        Console.WriteLine("\r\nAttributes for assembly: '{0}'", asm);
        ShowAttributeData(CustomAttributeData.GetCustomAttributes(asm));
        Console.WriteLine("\r\nAttributes for type: '{0}'", t);
        ShowAttributeData(CustomAttributeData.GetCustomAttributes(t));
        Console.WriteLine("\r\nAttributes for member: '{0}'", m);
        ShowAttributeData(CustomAttributeData.GetCustomAttributes(m));
        Console.WriteLine("\r\nAttributes for parameter: '{0}'", p);
        ShowAttributeData(CustomAttributeData.GetCustomAttributes(p[0]));
    }

    private static void ShowAttributeData(
        IList<CustomAttributeData> attributes)
    {
        foreach( CustomAttributeData cad in attributes )
        {
            Console.WriteLine("   {0}", cad);
            Console.WriteLine("      Constructor: '{0}'", cad.Constructor);

            Console.WriteLine("      Constructor arguments:");
            foreach( CustomAttributeTypedArgument cata
                in cad.ConstructorArguments )
            {
                ShowValueOrArray(cata);
            }

            Console.WriteLine("      Named arguments:");
            foreach( CustomAttributeNamedArgument cana
                in cad.NamedArguments )
            {
                Console.WriteLine("         MemberInfo: '{0}'",
                    cana.MemberInfo);
                ShowValueOrArray(cana.TypedValue);
            }
        }
    }

    private static void ShowValueOrArray(CustomAttributeTypedArgument cata)
    {
        if (cata.Value.GetType() == typeof(ReadOnlyCollection<CustomAttributeTypedArgument>))
        {
            Console.WriteLine("         Array of '{0}':", cata.ArgumentType);

            foreach (CustomAttributeTypedArgument cataElement in
                (ReadOnlyCollection<CustomAttributeTypedArgument>) cata.Value)
            {
                Console.WriteLine("             Type: '{0}'  Value: '{1}'",
                    cataElement.ArgumentType, cataElement.Value);
            }
        }
        else
        {
            Console.WriteLine("         Type: '{0}'  Value: '{1}'",
                cata.ArgumentType, cata.Value);
        }
    }
}

/* This code example produces output similar to the following:

Attributes for assembly: 'source, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
   [System.Runtime.CompilerServices.CompilationRelaxationsAttribute((Int32)8)]
      Constructor: 'Void .ctor(Int32)'
      Constructor arguments:
         Type: 'System.Int32'  Value: '8'
      Named arguments:
   [System.Runtime.CompilerServices.RuntimeCompatibilityAttribute(WrapNonExceptionThrows = True)]
      Constructor: 'Void .ctor()'
      Constructor arguments:
      Named arguments:
         MemberInfo: 'Boolean WrapNonExceptionThrows'
         Type: 'System.Boolean'  Value: 'True'
   [ExampleAttribute((ExampleKind)2, Note = "This is a note on the assembly.")]
      Constructor: 'Void .ctor(ExampleKind)'
      Constructor arguments:
         Type: 'ExampleKind'  Value: '2'
      Named arguments:
         MemberInfo: 'System.String Note'
         Type: 'System.String'  Value: 'This is a note on the assembly.'

Attributes for type: 'Test'
   [ExampleAttribute((ExampleKind)1, new String[3] { "String array argument, line 1", "String array argument, line 2", "String array argument, line 3" }, Note = "This is a note on the class.", Numbers = new Int32[3] { 53, 57, 59 })]
      Constructor: 'Void .ctor(ExampleKind, System.String[])'
      Constructor arguments:
         Type: 'ExampleKind'  Value: '1'
         Array of 'System.String[]':
             Type: 'System.String'  Value: 'String array argument, line 1'
             Type: 'System.String'  Value: 'String array argument, line 2'
             Type: 'System.String'  Value: 'String array argument, line 3'
      Named arguments:
         MemberInfo: 'System.String Note'
         Type: 'System.String'  Value: 'This is a note on the class.'
         MemberInfo: 'Int32[] Numbers'
         Array of 'System.Int32[]':
             Type: 'System.Int32'  Value: '53'
             Type: 'System.Int32'  Value: '57'
             Type: 'System.Int32'  Value: '59'

Attributes for member: 'Void TestMethod(System.Object)'
   [ExampleAttribute(Note = "This is a note on a method.")]
      Constructor: 'Void .ctor()'
      Constructor arguments:
      Named arguments:
         MemberInfo: 'System.String Note'
         Type: 'System.String'  Value: 'This is a note on a method.'

Attributes for parameter: 'System.Object arg'
   [ExampleAttribute()]
      Constructor: 'Void .ctor()'
      Constructor arguments:
      Named arguments:
*/

注解

无法执行在仅反射上下文中检查的代码,因此并不总是可以通过创建自定义属性的实例,然后使用 、 Attribute.GetCustomAttributesMemberInfo.GetCustomAttributes等方法检查自定义属性。 如果属性类型本身的代码加载到仅反射上下文中,则无法执行该代码。

CustomAttributeData 允许通过为属性提供抽象来检查仅反射上下文中的自定义属性。 此类的成员可用于获取属性的位置参数和命名参数。 ConstructorArguments使用 属性获取表示位置参数的结构CustomAttributeTypedArgument列表,并使用 NamedArguments 属性获取表示命名参数的结构列表CustomAttributeNamedArgument

备注

结构 CustomAttributeNamedArgument 仅提供有关用于获取和设置参数值的属性属性的信息。 若要获取 参数的类型和值,请使用 CustomAttributeNamedArgument.TypedValue 属性获取 CustomAttributeTypedArgument 结构。

如果具有 CustomAttributeTypedArgument 参数的结构(无论是命名的还是位置的),请使用 CustomAttributeTypedArgument.ArgumentType 属性获取类型,使用 CustomAttributeTypedArgument.Value 属性获取值。

备注

对于数组参数,属性CustomAttributeTypedArgument.Value返回 对象的泛型ReadOnlyCollection<T>CustomAttributeTypedArgumentCustomAttributeTypedArgument集合中的每个 对象都表示数组的相应元素。

CustomAttributeData 可以在执行上下文以及仅反射上下文中使用。 例如,你可能希望避免加载包含自定义特性代码的程序集。 CustomAttributeData使用 类不同于使用 等Attribute.GetCustomAttributes方法:

  • 的属性和方法 CustomAttributeData 仅为你提供为特性实例指定的值,而不是构造函数的语义。 例如,属性的字符串参数可能在内部转换为其他表示形式,并返回规范形式;或 属性在执行实际属性代码时可能会产生副作用。

  • 的属性和方法 CustomAttributeData 不允许检索从基类继承的自定义属性。

若要创建 类的 CustomAttributeData 实例,请使用 static Visual Basic 中的 Shared () GetCustomAttributes 工厂方法。

构造函数

CustomAttributeData()

初始化 CustomAttributeData 类的新实例。

属性

AttributeType

获取属性的类型。

Constructor

获取一个 ConstructorInfo 对象,表示应已初始化自定义属性的构造函数。

ConstructorArguments

获取为由 CustomAttributeData 对象表示的特性实例指定的位置参数列表。

NamedArguments

获取为由 CustomAttributeData 对象表示的特性实例指定的命名参数列表。

方法

Equals(Object)

返回一个值,该值指示此实例是否与指定的对象相等。

Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
GetCustomAttributes(Assembly)

返回 CustomAttributeData 对象列表,这些对象表示已应用到目标程序集的特性相关数据。

GetCustomAttributes(MemberInfo)

返回 CustomAttributeData 对象列表,这些对象表示已应用到目标成员的特性相关数据。

GetCustomAttributes(Module)

返回 CustomAttributeData 对象列表,这些对象表示已应用到目标模块的特性相关数据。

GetCustomAttributes(ParameterInfo)

返回 CustomAttributeData 对象列表,这些对象表示已应用到目标参数的特性相关数据。

GetHashCode()

用作特定类型的哈希函数。

GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetType()

获取当前实例的 Type

(继承自 Object)
MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
ToString()

返回自定义特性的字符串表示形式。

ToString()

返回表示当前对象的字符串。

(继承自 Object)

适用于

产品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

另请参阅