AttributeMap.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #if !NO_RUNTIME
  2. using System;
  3. using System.Reflection;
  4. namespace ProtoBuf.Meta
  5. {
  6. internal abstract class AttributeMap
  7. {
  8. #if DEBUG
  9. [Obsolete("Please use AttributeType instead")]
  10. new public Type GetType() => AttributeType;
  11. #endif
  12. public override string ToString() => AttributeType?.FullName ?? "";
  13. public abstract bool TryGet(string key, bool publicOnly, out object value);
  14. public bool TryGet(string key, out object value)
  15. {
  16. return TryGet(key, true, out value);
  17. }
  18. public abstract Type AttributeType { get; }
  19. public static AttributeMap[] Create(TypeModel model, Type type, bool inherit)
  20. {
  21. #if COREFX || PROFILE259
  22. Attribute[] all = System.Linq.Enumerable.ToArray(System.Linq.Enumerable.OfType<Attribute>(type.GetTypeInfo().GetCustomAttributes(inherit)));
  23. #else
  24. object[] all = type.GetCustomAttributes(inherit);
  25. #endif
  26. AttributeMap[] result = new AttributeMap[all.Length];
  27. for(int i = 0 ; i < all.Length ; i++)
  28. {
  29. result[i] = new ReflectionAttributeMap((Attribute)all[i]);
  30. }
  31. return result;
  32. }
  33. public static AttributeMap[] Create(TypeModel model, MemberInfo member, bool inherit)
  34. {
  35. #if COREFX || PROFILE259
  36. Attribute[] all = System.Linq.Enumerable.ToArray(System.Linq.Enumerable.OfType<Attribute>(member.GetCustomAttributes(inherit)));
  37. #else
  38. object[] all = member.GetCustomAttributes(inherit);
  39. #endif
  40. AttributeMap[] result = new AttributeMap[all.Length];
  41. for(int i = 0 ; i < all.Length ; i++)
  42. {
  43. result[i] = new ReflectionAttributeMap((Attribute)all[i]);
  44. }
  45. return result;
  46. }
  47. public static AttributeMap[] Create(TypeModel model, Assembly assembly)
  48. {
  49. #if COREFX || PROFILE259
  50. Attribute[] all = System.Linq.Enumerable.ToArray(assembly.GetCustomAttributes());
  51. #else
  52. const bool inherit = false;
  53. object[] all = assembly.GetCustomAttributes(inherit);
  54. #endif
  55. AttributeMap[] result = new AttributeMap[all.Length];
  56. for(int i = 0 ; i < all.Length ; i++)
  57. {
  58. result[i] = new ReflectionAttributeMap((Attribute)all[i]);
  59. }
  60. return result;
  61. }
  62. public abstract object Target { get; }
  63. private sealed class ReflectionAttributeMap : AttributeMap
  64. {
  65. private readonly Attribute attribute;
  66. public ReflectionAttributeMap(Attribute attribute)
  67. {
  68. this.attribute = attribute;
  69. }
  70. public override object Target => attribute;
  71. public override Type AttributeType => attribute.GetType();
  72. public override bool TryGet(string key, bool publicOnly, out object value)
  73. {
  74. MemberInfo[] members = Helpers.GetInstanceFieldsAndProperties(attribute.GetType(), publicOnly);
  75. foreach (MemberInfo member in members)
  76. {
  77. if (string.Equals(member.Name, key, StringComparison.OrdinalIgnoreCase))
  78. {
  79. if (member is PropertyInfo prop) {
  80. value = prop.GetValue(attribute, null);
  81. return true;
  82. }
  83. if (member is FieldInfo field) {
  84. value = field.GetValue(attribute);
  85. return true;
  86. }
  87. throw new NotSupportedException(member.GetType().Name);
  88. }
  89. }
  90. value = null;
  91. return false;
  92. }
  93. }
  94. }
  95. }
  96. #endif