| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq.Expressions; |
| | | using System.Reflection; |
| | | using System.Text; |
| | | |
| | | namespace UnityEditor.PostProcessing |
| | | { |
| | | public static class ReflectionUtils |
| | | { |
| | | static Dictionary<KeyValuePair<object, string>, FieldInfo> s_FieldInfoFromPaths = new Dictionary<KeyValuePair<object, string>, FieldInfo>(); |
| | | |
| | | public static FieldInfo GetFieldInfoFromPath(object source, string path) |
| | | { |
| | | FieldInfo field = null; |
| | | var kvp = new KeyValuePair<object, string>(source, path); |
| | | |
| | | if (!s_FieldInfoFromPaths.TryGetValue(kvp, out field)) |
| | | { |
| | | var splittedPath = path.Split('.'); |
| | | var type = source.GetType(); |
| | | |
| | | foreach (var t in splittedPath) |
| | | { |
| | | field = type.GetField(t, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); |
| | | |
| | | if (field == null) |
| | | break; |
| | | |
| | | type = field.FieldType; |
| | | } |
| | | |
| | | s_FieldInfoFromPaths.Add(kvp, field); |
| | | } |
| | | |
| | | return field; |
| | | } |
| | | |
| | | public static string GetFieldPath<T, TValue>(Expression<Func<T, TValue>> expr) |
| | | { |
| | | MemberExpression me; |
| | | switch (expr.Body.NodeType) |
| | | { |
| | | case ExpressionType.Convert: |
| | | case ExpressionType.ConvertChecked: |
| | | var ue = expr.Body as UnaryExpression; |
| | | me = (ue != null ? ue.Operand : null) as MemberExpression; |
| | | break; |
| | | default: |
| | | me = expr.Body as MemberExpression; |
| | | break; |
| | | } |
| | | |
| | | var members = new List<string>(); |
| | | while (me != null) |
| | | { |
| | | members.Add(me.Member.Name); |
| | | me = me.Expression as MemberExpression; |
| | | } |
| | | |
| | | var sb = new StringBuilder(); |
| | | for (int i = members.Count - 1; i >= 0; i--) |
| | | { |
| | | sb.Append(members[i]); |
| | | if (i > 0) sb.Append('.'); |
| | | } |
| | | |
| | | return sb.ToString(); |
| | | } |
| | | |
| | | public static object GetFieldValue(object source, string name) |
| | | { |
| | | var type = source.GetType(); |
| | | |
| | | while (type != null) |
| | | { |
| | | var f = type.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); |
| | | if (f != null) |
| | | return f.GetValue(source); |
| | | |
| | | type = type.BaseType; |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | public static object GetFieldValueFromPath(object source, ref Type baseType, string path) |
| | | { |
| | | var splittedPath = path.Split('.'); |
| | | object srcObject = source; |
| | | |
| | | foreach (var t in splittedPath) |
| | | { |
| | | var fieldInfo = baseType.GetField(t, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); |
| | | |
| | | if (fieldInfo == null) |
| | | { |
| | | baseType = null; |
| | | break; |
| | | } |
| | | |
| | | baseType = fieldInfo.FieldType; |
| | | srcObject = GetFieldValue(srcObject, t); |
| | | } |
| | | |
| | | return baseType == null |
| | | ? null |
| | | : srcObject; |
| | | } |
| | | |
| | | public static object GetParentObject(string path, object obj) |
| | | { |
| | | var fields = path.Split('.'); |
| | | |
| | | if (fields.Length == 1) |
| | | return obj; |
| | | |
| | | var info = obj.GetType().GetField(fields[0], BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); |
| | | obj = info.GetValue(obj); |
| | | |
| | | return GetParentObject(string.Join(".", fields, 1, fields.Length - 1), obj); |
| | | } |
| | | } |
| | | } |
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Linq.Expressions;
|
| | | using System.Reflection;
|
| | | using System.Text;
|
| | |
|
| | | namespace UnityEditor.PostProcessing
|
| | | {
|
| | | public static class ReflectionUtils
|
| | | {
|
| | | static Dictionary<KeyValuePair<object, string>, FieldInfo> s_FieldInfoFromPaths = new Dictionary<KeyValuePair<object, string>, FieldInfo>();
|
| | |
|
| | | public static FieldInfo GetFieldInfoFromPath(object source, string path)
|
| | | {
|
| | | FieldInfo field = null;
|
| | | var kvp = new KeyValuePair<object, string>(source, path);
|
| | |
|
| | | if (!s_FieldInfoFromPaths.TryGetValue(kvp, out field))
|
| | | {
|
| | | var splittedPath = path.Split('.');
|
| | | var type = source.GetType();
|
| | |
|
| | | foreach (var t in splittedPath)
|
| | | {
|
| | | field = type.GetField(t, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
| | |
|
| | | if (field == null)
|
| | | break;
|
| | |
|
| | | type = field.FieldType;
|
| | | }
|
| | |
|
| | | s_FieldInfoFromPaths.Add(kvp, field);
|
| | | }
|
| | |
|
| | | return field;
|
| | | }
|
| | |
|
| | | public static string GetFieldPath<T, TValue>(Expression<Func<T, TValue>> expr)
|
| | | {
|
| | | MemberExpression me;
|
| | | switch (expr.Body.NodeType)
|
| | | {
|
| | | case ExpressionType.Convert:
|
| | | case ExpressionType.ConvertChecked:
|
| | | var ue = expr.Body as UnaryExpression;
|
| | | me = (ue != null ? ue.Operand : null) as MemberExpression;
|
| | | break;
|
| | | default:
|
| | | me = expr.Body as MemberExpression;
|
| | | break;
|
| | | }
|
| | |
|
| | | var members = new List<string>();
|
| | | while (me != null)
|
| | | {
|
| | | members.Add(me.Member.Name);
|
| | | me = me.Expression as MemberExpression;
|
| | | }
|
| | |
|
| | | var sb = new StringBuilder();
|
| | | for (int i = members.Count - 1; i >= 0; i--)
|
| | | {
|
| | | sb.Append(members[i]);
|
| | | if (i > 0) sb.Append('.');
|
| | | }
|
| | |
|
| | | return sb.ToString();
|
| | | }
|
| | |
|
| | | public static object GetFieldValue(object source, string name)
|
| | | {
|
| | | var type = source.GetType();
|
| | |
|
| | | while (type != null)
|
| | | {
|
| | | var f = type.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
| | | if (f != null)
|
| | | return f.GetValue(source);
|
| | |
|
| | | type = type.BaseType;
|
| | | }
|
| | |
|
| | | return null;
|
| | | }
|
| | |
|
| | | public static object GetFieldValueFromPath(object source, ref Type baseType, string path)
|
| | | {
|
| | | var splittedPath = path.Split('.');
|
| | | object srcObject = source;
|
| | |
|
| | | foreach (var t in splittedPath)
|
| | | {
|
| | | var fieldInfo = baseType.GetField(t, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
| | |
|
| | | if (fieldInfo == null)
|
| | | {
|
| | | baseType = null;
|
| | | break;
|
| | | }
|
| | |
|
| | | baseType = fieldInfo.FieldType;
|
| | | srcObject = GetFieldValue(srcObject, t);
|
| | | }
|
| | |
|
| | | return baseType == null
|
| | | ? null
|
| | | : srcObject;
|
| | | }
|
| | |
|
| | | public static object GetParentObject(string path, object obj)
|
| | | {
|
| | | var fields = path.Split('.');
|
| | |
|
| | | if (fields.Length == 1)
|
| | | return obj;
|
| | |
|
| | | var info = obj.GetType().GetField(fields[0], BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
| | | obj = info.GetValue(obj);
|
| | |
|
| | | return GetParentObject(string.Join(".", fields, 1, fields.Length - 1), obj);
|
| | | }
|
| | | }
|
| | | }
|