UnityGetter.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using System;
  2. using System.Linq;
  3. using System.Reflection;
  4. using Chronos.Reflection.Internal;
  5. using UnityEngine;
  6. using UnityObject = UnityEngine.Object;
  7. namespace Chronos.Reflection
  8. {
  9. [Serializable]
  10. public class UnityGetter : UnityMember
  11. {
  12. private enum SourceType
  13. {
  14. Unknown,
  15. Field,
  16. Property,
  17. Method
  18. }
  19. private SourceType sourceType = SourceType.Unknown;
  20. /// <summary>
  21. /// The underlying reflected field, or null if the getter is a property or method.
  22. /// </summary>
  23. public FieldInfo fieldInfo { get; private set; }
  24. /// <summary>
  25. /// The underlying property field, or null if the getter is a field or method.
  26. /// </summary>
  27. public PropertyInfo propertyInfo { get; private set; }
  28. /// <summary>
  29. /// The underlying reflected method, or null if the getter is a field or property.
  30. /// </summary>
  31. public MethodInfo methodInfo { get; private set; }
  32. /// <summary>
  33. /// Whether the reflected method is an extension method.
  34. /// </summary>
  35. public bool isExtension { get; private set; }
  36. [SerializeField]
  37. private string[] _parameterTypes;
  38. private Type[] __parameterTypes;
  39. /// <summary>
  40. /// The types of the method's parameters.
  41. /// </summary>
  42. public Type[] parameterTypes
  43. {
  44. get { return __parameterTypes; }
  45. set { __parameterTypes = value; isReflected = false; }
  46. }
  47. #region Constructors
  48. public UnityGetter() { }
  49. public UnityGetter(string name) : base(name) { }
  50. public UnityGetter(string name, UnityObject target) : base(name, target) { }
  51. public UnityGetter(string component, string name) : base(component, name) { }
  52. public UnityGetter(string component, string name, UnityObject target) : base(component, name, target) { }
  53. public UnityGetter(string name, Type[] parameterTypes) : base(name) { this.parameterTypes = parameterTypes; }
  54. public UnityGetter(string name, Type[] parameterTypes, UnityObject target) : this(name, parameterTypes) { this.target = target; Reflect(); }
  55. public UnityGetter(string component, string name, Type[] parameterTypes) : base(component, name) { this.parameterTypes = parameterTypes; }
  56. public UnityGetter(string component, string name, Type[] parameterTypes, UnityObject target) : this(component, name, parameterTypes) { this.target = target; Reflect(); }
  57. #endregion
  58. /// <inheritdoc />
  59. public override void Reflect()
  60. {
  61. EnsureAssigned();
  62. EnsureTargeted();
  63. this.fieldInfo = null;
  64. this.propertyInfo = null;
  65. this.methodInfo = null;
  66. this.sourceType = SourceType.Unknown;
  67. MemberInfo variableInfo;
  68. MethodInfo methodInfo;
  69. UnityReflectionException exception;
  70. if (UnityMemberHelper.TryReflectVariable(out variableInfo, out exception, reflectionTarget, name))
  71. {
  72. fieldInfo = variableInfo as FieldInfo;
  73. propertyInfo = variableInfo as PropertyInfo;
  74. if (fieldInfo != null)
  75. {
  76. sourceType = SourceType.Field;
  77. }
  78. else if (propertyInfo != null)
  79. {
  80. sourceType = SourceType.Property;
  81. }
  82. }
  83. else if (UnityMemberHelper.TryReflectMethod(out methodInfo, out exception, reflectionTarget, name, parameterTypes))
  84. {
  85. this.methodInfo = methodInfo;
  86. isExtension = methodInfo.IsExtension();
  87. sourceType = SourceType.Method;
  88. }
  89. else
  90. {
  91. throw new UnityReflectionException("No matching field, property or method found.");
  92. }
  93. isReflected = true;
  94. }
  95. /// <summary>
  96. /// Retrieves the value of the getter.
  97. /// </summary>
  98. public object Get(params object[] parameters)
  99. {
  100. EnsureReflected();
  101. switch (sourceType)
  102. {
  103. case SourceType.Field: return fieldInfo.GetValue(reflectionTarget);
  104. case SourceType.Property: return propertyInfo.GetValue(reflectionTarget, null);
  105. case SourceType.Method: return UnityMemberHelper.InvokeMethod(reflectionTarget, methodInfo, isExtension, parameters);
  106. default: throw new UnityReflectionException();
  107. }
  108. }
  109. /// <summary>
  110. /// Retrieves the value of the getter casted to the specified type.
  111. /// </summary>
  112. public T Get<T>(params object[] parameters)
  113. {
  114. return (T)Get(parameters);
  115. }
  116. /// <summary>
  117. /// The return type of the reflected field, property of method.
  118. /// </summary>
  119. public Type returnType
  120. {
  121. get
  122. {
  123. EnsureReflected();
  124. switch (sourceType)
  125. {
  126. case SourceType.Field: return fieldInfo.FieldType;
  127. case SourceType.Property: return propertyInfo.PropertyType;
  128. case SourceType.Method: return methodInfo.ReturnType;
  129. default: throw new UnityReflectionException();
  130. }
  131. }
  132. }
  133. public override bool Corresponds(UnityMember other)
  134. {
  135. var corresponds = other is UnityGetter && base.Corresponds(other);
  136. corresponds &= (parameterTypes == null) == (((UnityGetter)other).parameterTypes == null);
  137. if (parameterTypes != null)
  138. {
  139. corresponds &= parameterTypes.SequenceEqual(((UnityGetter)other).parameterTypes);
  140. }
  141. return corresponds;
  142. }
  143. }
  144. }