using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; namespace Utils.Refelector { public class ReflectionUtil { public static TResult GetPrivateField(TClass obj, string field) { Type type = obj.GetType(); var privateField = type.GetField(field, BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); return (TResult)privateField.GetValue(obj); } /// /// 执行静态非公有方法。 /// 当方法有重载时,该方法报错,需要使用指定了参数类型的那个方法 /// 即:ExecuteStaticFunc(Type type, string func, Type[] types, params object[] parameters) /// /// 方法所在类的类型 /// 方法名 /// 参数 public static object ExecuteNotPublicStaticFunc(Type type, string func, params object[] parameters) { return type.GetMethod(func, BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Static).Invoke(null, parameters); } /// /// 执行静态非公有方法 /// /// 方法所在类的类型 /// 方法名 /// 方法的参数的类型,其顺序为方法的参数的顺序 /// 参数 public static object ExecuteNotPublicStaticFunc(Type type, string func, Type[] types, params object[] parameters) { if (types.Length != parameters.Length) throw new ArgumentException("第三个参数和后面的参数的个数不匹配"); var methods = type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic); return GetMethod(methods, types).Invoke(null, parameters); } /// /// 从指定的方法数组中,找出方法的参数的Type为指定Type的方法。 /// 即:找出参数类型的Type的个数与顺序符合本方法第二个参数的方法。 /// 没找到则返回null /// public static MethodInfo GetMethod(MethodInfo[] methods, Type[] types) { foreach (var item in methods) { var param = item.GetParameters(); if (param.Length != types.Length) continue; bool tatolSame = true; for (int i = 0; i < types.Length; i++) { if (types[i] != param[i].ParameterType) { tatolSame = false; break; } } if (tatolSame) return item; } return null; } //public static PropertyInfo[] GetField(TClass obj) //{ // var type = obj.GetType(); // return type.GetProperties(); //} //public static void SetValue(TClass obj) //{ // var properties = GetField(obj); // properties[0].SetValue(obj, "", null); //} /// /// 获取公共属性的值。 /// 忽略索引。如:public char this[int index] { get; } /// 忽略不可读的属性 /// public static Dictionary GetPublicPropertyValues(TClass obj) { Dictionary result = new Dictionary(); if (obj == null) return result; var properties = obj.GetType().GetProperties(); foreach (var field in properties) { if (field.GetIndexParameters().Length > 0)//如果是索引,则忽略。索引:public char this[int index] { get; } continue; if (!field.CanRead) continue; result.Add(field.Name, field.GetValue(obj, null)); } return result; } /// /// 设置指定对象的值为values /// 忽略索引。如:public char this[int index] { get; } /// 忽略不可写的属性 /// public static void SetValues(TClass obj, Dictionary values) { if (obj == null) return; if (values == null || values.Count == 0) return; var dmoType = obj.GetType(); var properties = dmoType.GetProperties(); foreach (var field in properties) { if (field.GetIndexParameters().Length > 0)//如果是索引,则忽略。索引:public char this[int index] { get; } continue; if (!field.CanWrite) continue; var propertyType = dmoType.GetProperty(field.Name).PropertyType; if (values.Keys.Contains(field.Name)) { object value = values[field.Name]; if (value == null || !propertyType.Equals(value.GetType())) { value = ChangeType(propertyType, value); } dmoType.GetProperty(field.Name).SetValue(obj, value, null); } } } private static object ChangeType(Type propertyType, object value) {//TODO:这个是为了处理在设置清单的值时,由于给定的值的类型是string类型,导致在设置值时类型不正确。之所以“给定的值的类型是string类型”,是因为在CommanRow类中,获取控件值时返回的类型是string(public string this[string field]的这个)。如果能解决上述问题,则不需要这个方法,引用这个方法的地方,也就可以修改之o if (propertyType.Equals(typeof(long))) { if (value == null || string.IsNullOrEmpty(value.ToString())) return 0; return long.Parse(value.ToString()); } else if (propertyType.Equals(typeof(long?))) { if (value == null || string.IsNullOrEmpty(value.ToString())) return null; return long.Parse(value.ToString()); } else if (propertyType.Equals(typeof(int))) { if (value == null || string.IsNullOrEmpty(value.ToString())) return 0; return int.Parse(value.ToString()); } else if (propertyType.Equals(typeof(int?))) { if (value == null || string.IsNullOrEmpty(value.ToString())) return null; return int.Parse(value.ToString()); } else if (propertyType.Equals(typeof(decimal))) { if (value == null || string.IsNullOrEmpty(value.ToString())) return 0; return decimal.Parse(value.ToString()); } else if (propertyType.Equals(typeof(decimal?))) { if (value == null || string.IsNullOrEmpty(value.ToString())) return null; return decimal.Parse(value.ToString()); } else if (propertyType.Equals(typeof(bool))) { if (value == null || string.IsNullOrEmpty(value.ToString())) return false; return bool.Parse(value.ToString()); } else if (propertyType.Equals(typeof(bool?))) { if (value == null || string.IsNullOrEmpty(value.ToString())) return null; return bool.Parse(value.ToString()); } else if (propertyType.Equals(typeof(DateTime))) { if (value == null || string.IsNullOrEmpty(value.ToString())) return DateTime.Now;//TODO:如何处理? return bool.Parse(value.ToString()); } else if (propertyType.Equals(typeof(DateTime?))) { if (value == null || string.IsNullOrEmpty(value.ToString())) return null; return DateTime.Parse(value.ToString()); } else throw new ApplicationException("未处理"); } } }