dwelling acts 1 & 3
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
9.7 KiB

1 year ago
using System;
using System.Linq;
using System.Reflection;
using UnityEditor;
namespace FullscreenEditor {
/// <summary>Class containing method extensions for getting private and internal members.</summary>
public static class ReflectionUtility {
private static Assembly[] cachedAssemblies;
public const BindingFlags FULL_BINDING = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
/// <summary>Find a type by its name.</summary>
public static Type FindClass(string name) {
// return typeof(Editor).Assembly.GetType(name, false, true);
var result = FindTypeInAssembly(name, typeof(Editor).Assembly);
if (result != null)
return result;
if (cachedAssemblies == null)
cachedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
for (var i = 0; i < cachedAssemblies.Length; i++) {
result = FindTypeInAssembly(name, cachedAssemblies[i]);
if (result != null)
return result;
}
return result;
}
private static Type FindTypeInAssembly(string name, Assembly assembly) {
return assembly == null ?
null :
assembly.GetType(name, false, true);
}
/// <summary>Find a field of a type by its name.</summary>
public static FieldInfo FindField(this Type type, string fieldName, bool throwNotFound = true) {
if (type == null)
throw new ArgumentNullException("type");
var field = type.GetField(fieldName, FULL_BINDING);
if (field == null && throwNotFound)
throw new MissingFieldException(type.FullName, fieldName);
return field;
}
/// <summary>Find a property of a type by its name.</summary>
public static PropertyInfo FindProperty(this Type type, string propertyName, bool throwNotFound = true) {
if (type == null)
throw new ArgumentNullException("type");
var prop = type.GetProperty(propertyName, FULL_BINDING);
if (prop == null && throwNotFound)
throw new MissingMemberException(type.FullName, propertyName);
return prop;
}
/// <summary>Find a method of a type by its name.</summary>
public static MethodInfo FindMethod(this Type type, string methodName, Type[] args = null, bool throwNotFound = true) {
if (type == null)
throw new ArgumentNullException("type");
MethodInfo method;
if (args == null) {
method = type.GetMethod(methodName, FULL_BINDING);
// method = type.GetMethods(FULL_BINDING)
// .Where(m => m.Name == methodName)
// .FirstOrDefault();
} else {
method = type.GetMethod(methodName, FULL_BINDING, null, args, null);
// There are very specific cases where the above method may not bind properly
// e.g. when the method declares an enum and the arg type is an int, so we ignore the args
// and hope that there are no ambiguity of methods
if (method == null) {
method = FindMethod(type, methodName, null, throwNotFound);
if (method != null && method.GetParameters().Length != args.Length)
method = null;
}
}
if (method == null && throwNotFound)
throw new MissingMethodException(type.FullName, methodName);
return method;
}
/// <summary>Get the value of the static field.</summary>
public static T GetFieldValue<T>(this Type type, string fieldName) { return (T)type.FindField(fieldName).GetValue(null); }
/// <summary>Get the value of the instance field.</summary>
public static T GetFieldValue<T>(this object obj, string fieldName) { return (T)obj.GetType().FindField(fieldName).GetValue(obj); }
/// <summary>Set the value of the static field.</summary>
public static void SetFieldValue(this Type type, string fieldName, object value) { type.FindField(fieldName).SetValue(null, value); }
/// <summary>Set the value of the instance field.</summary>
public static void SetFieldValue(this object obj, string fieldName, object value) { obj.GetType().FindField(fieldName).SetValue(obj, value); }
/// <summary>Get the value of the static property.</summary>
public static T GetPropertyValue<T>(this Type type, string propertyName) { return (T)type.FindProperty(propertyName).GetValue(null, null); }
/// <summary>Get the value of the instance property.</summary>
public static T GetPropertyValue<T>(this object obj, string propertyName) { return (T)obj.GetType().FindProperty(propertyName).GetValue(obj, null); }
/// <summary>Set the value of the static property.</summary>
public static void SetPropertyValue(this Type type, string propertyName, object value) { type.FindProperty(propertyName).SetValue(null, value, null); }
/// <summary>Set the value of the instance property.</summary>
public static void SetPropertyValue(this object obj, string propertyName, object value) { obj.GetType().FindProperty(propertyName).SetValue(obj, value, null); }
/// <summary>Invoke a static method on the type and return the result.</summary>
public static T InvokeMethod<T>(this Type type, string methodName, params object[] args) { return (T)type.FindMethod(methodName, args.Select(a => a.GetType()).ToArray()).Invoke(null, args); }
/// <summary>Invoke a method on the object instance and return the result.</summary>
public static T InvokeMethod<T>(this object obj, string methodName, params object[] args) { return (T)obj.GetType().FindMethod(methodName, args.Select(a => a.GetType()).ToArray()).Invoke(obj, args); }
/// <summary>Invoke a static method on the type.</summary>
public static void InvokeMethod(this Type type, string methodName, params object[] args) { type.FindMethod(methodName, args.Select(a => a.GetType()).ToArray()).Invoke(null, args); }
/// <summary>Invoke a method on the object instance.</summary>
public static void InvokeMethod(this object obj, string methodName, params object[] args) { obj.GetType().FindMethod(methodName, args.Select(a => a.GetType()).ToArray()).Invoke(obj, args); }
/// <summary>Returns wheter the given type is the same as another one.</summary>
/// <param name="toCheck">Type that will be checked.</param>
/// <param name="type">Type to check against.</param>
/// <param name="orInherited">Returns true if the checked type is inherited from the type argument.</param>
public static bool IsOfType(this Type toCheck, Type type, bool orInherited = true) {
return type == toCheck || (orInherited && type.IsAssignableFrom(toCheck));
}
/// <summary>Returns wheter the given instance is of a given type.</summary>
/// <param name="obj">The instance to check.</param>
/// <param name="type">Type to check against.</param>
/// <param name="orInherited">Returns true if the instance is inherited from the type argument.</param>
public static bool IsOfType<T>(this T obj, Type type, bool orInherited = true) {
return obj.GetType().IsOfType(type, orInherited);
}
/// <summary>Throws an exception if the instance is not of the given type.</summary>
/// <param name="obj">The instance to check.</param>
/// <param name="type">Type to check against.</param>
/// <param name="orInherited">Do not throw if the instance is inherited from the type argument.</param>
public static void EnsureOfType<T>(this T obj, Type type, bool orInherited = true) {
if (!obj.IsOfType(type, orInherited))
throw new InvalidCastException(
string.Format("Object {0} must be of type {1}{2}",
obj.GetType().FullName,
type.FullName,
orInherited? " or inherited from it": ""
)
);
}
/// <summary>Returns whether the type defines the static field.</summary>
public static bool HasField(this Type type, string fieldName) {
return type.FindField(fieldName, false) != null;
}
/// <summary>Returns whether the type defines the static property.</summary>
public static bool HasProperty(this Type type, string propertyName) {
return type.FindProperty(propertyName, false) != null;
}
/// <summary>Returns whether the type defines the static method.</summary>
public static bool HasMethod(this Type type, string methodName, Type[] args = null) {
return type.FindMethod(methodName, args, false) != null;
}
/// <summary>Returns whether the object type defines the instance field.</summary>
public static bool HasField(this object obj, string fieldName) {
return obj.GetType().HasField(fieldName);
}
/// <summary>Returns whether the object type defines the instance property.</summary>
public static bool HasProperty(this object obj, string propertyName) {
return obj.GetType().HasProperty(propertyName);
}
/// <summary>Returns whether the object type defines the instance method.</summary>
public static bool HasMethod(this object obj, string methodName, Type[] args = null) {
return obj.GetType().HasMethod(methodName, args);
}
}
}