windows C#-利用反射访问特性

[复制链接]
发表于 2025-12-19 01:31:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
你可以界说自界说特性并将其放入源代码中这一究竟,在没有检索该信息并对其举行操纵的方法的情况下将没有任何代价。 通过利用反射,可以检索通过自界说特性界说的信息。 告急方法是 GetCustomAttributes,它返回对象数组,这些对象在运行时等效于源代码特性。 此方法有很多重载版本。 
特性规范,比方:
  1. [Author("P. Ackerman", Version = 1.1)]
  2. class SampleClass { }
复制代码
在概念上等效于以下代码:
  1. var anonymousAuthorObject = new Author("P. Ackerman")
  2. {
  3.     Version = 1.1
  4. };
复制代码
但是,在为特性查询 SampleClass 之前,代码将不会实行。 对 SampleClass 调用 GetCustomAttributes 会导致构造并初始化一个 Author 对象。 如果该类具有其他特性,则将以雷同方式构造其他特性对象。 然后 GetCustomAttributes 会以数组情势返回 Author 对象和任何其他特性对象。 之后你便可以循环访问此数组,根据每个数组元素的范例确定所应用的特性,并从特性对象中提取信息。
下面是完备的示例。 界说自界说特性、将其应用于多个实体,并通过反射对其举行检索。
  1. // Multiuse attribute.
  2. [System.AttributeUsage(System.AttributeTargets.Class |
  3.                        System.AttributeTargets.Struct,
  4.                        AllowMultiple = true)  // Multiuse attribute.
  5. ]
  6. public class AuthorAttribute : System.Attribute
  7. {
  8.     string Name;
  9.     public double Version;
  10.     public AuthorAttribute(string name)
  11.     {
  12.         Name = name;
  13.         // Default value.
  14.         Version = 1.0;
  15.     }
  16.     public string GetName() => Name;
  17. }
  18. // Class with the Author attribute.
  19. [Author("P. Ackerman")]
  20. public class FirstClass
  21. {
  22.     // ...
  23. }
  24. // Class without the Author attribute.
  25. public class SecondClass
  26. {
  27.     // ...
  28. }
  29. // Class with multiple Author attributes.
  30. [Author("P. Ackerman"), Author("R. Koch", Version = 2.0)]
  31. public class ThirdClass
  32. {
  33.     // ...
  34. }
  35. class TestAuthorAttribute
  36. {
  37.     public static void Test()
  38.     {
  39.         PrintAuthorInfo(typeof(FirstClass));
  40.         PrintAuthorInfo(typeof(SecondClass));
  41.         PrintAuthorInfo(typeof(ThirdClass));
  42.     }
  43.     private static void PrintAuthorInfo(System.Type t)
  44.     {
  45.         System.Console.WriteLine($"Author information for {t}");
  46.         // Using reflection.
  47.         System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);  // Reflection.
  48.         // Displaying output.
  49.         foreach (System.Attribute attr in attrs)
  50.         {
  51.             if (attr is AuthorAttribute a)
  52.             {
  53.                 System.Console.WriteLine($"   {a.GetName()}, version {a.Version:f}");
  54.             }
  55.         }
  56.     }
  57. }
  58. /* Output:
  59.     Author information for FirstClass
  60.        P. Ackerman, version 1.00
  61.     Author information for SecondClass
  62.     Author information for ThirdClass
  63.        R. Koch, version 2.00
  64.        P. Ackerman, version 1.00
  65. */
复制代码
怎样利用特性创建 C/C++ 连合

通过利用特性,可自界说结构在内存中的结构方式。 比方,可利用 StructLayout(LayoutKind.Explicit) 和 FieldOffset 特性在 C/C++ 中创建所谓的连合。
在此代码段中,TestUnion 的全部字段均从内存中的同一位置开始。
  1. [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
  2. struct TestUnion
  3. {
  4.     [System.Runtime.InteropServices.FieldOffset(0)]
  5.     public int i;
  6.     [System.Runtime.InteropServices.FieldOffset(0)]
  7.     public double d;
  8.     [System.Runtime.InteropServices.FieldOffset(0)]
  9.     public char c;
  10.     [System.Runtime.InteropServices.FieldOffset(0)]
  11.     public byte b;
  12. }
复制代码
以下代码是另一个示例,此中的字段从差别的显式设置位置开始。
  1. [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
  2. struct TestExplicit
  3. {
  4.     [System.Runtime.InteropServices.FieldOffset(0)]
  5.     public long lg;
  6.     [System.Runtime.InteropServices.FieldOffset(0)]
  7.     public int i1;
  8.     [System.Runtime.InteropServices.FieldOffset(4)]
  9.     public int i2;
  10.     [System.Runtime.InteropServices.FieldOffset(8)]
  11.     public double d;
  12.     [System.Runtime.InteropServices.FieldOffset(12)]
  13.     public char c;
  14.     [System.Runtime.InteropServices.FieldOffset(14)]
  15.     public byte b;
  16. }
复制代码
组合的两个整数字段 i1 和 i2 与 lg 共享雷同的内存位置。 lg 利用前 8 个字节,或 i1 利用前 4 个字节且 i2 利用后 4 个字节。 利用平台调用时,这种对结构结构的控制很有效。 

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表