|
|
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, TResult>(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);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 执行静态非公有方法。
|
|
|
/// <para>当方法有重载时,该方法报错,需要使用指定了参数类型的那个方法</para>
|
|
|
/// <para>即:ExecuteStaticFunc(Type type, string func, Type[] types, params object[] parameters)</para>
|
|
|
/// </summary>
|
|
|
/// <param name="type">方法所在类的类型</param>
|
|
|
/// <param name="func">方法名</param>
|
|
|
/// <param name="parameters">参数</param>
|
|
|
public static object ExecuteNotPublicStaticFunc(Type type, string func, params object[] parameters)
|
|
|
{
|
|
|
return type.GetMethod(func, BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Static).Invoke(null, parameters);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 执行静态非公有方法
|
|
|
/// </summary>
|
|
|
/// <param name="type">方法所在类的类型</param>
|
|
|
/// <param name="func">方法名</param>
|
|
|
/// <param name="types">方法的参数的类型,其顺序为方法的参数的顺序</param>
|
|
|
/// <param name="parameters">参数</param>
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 从指定的方法数组中,找出方法的参数的Type为指定Type的方法。
|
|
|
/// <para>即:找出参数类型的Type的个数与顺序符合本方法第二个参数的方法。</para>
|
|
|
/// <para>没找到则返回null</para>
|
|
|
/// </summary>
|
|
|
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>(TClass obj)
|
|
|
//{
|
|
|
// var type = obj.GetType();
|
|
|
// return type.GetProperties();
|
|
|
//}
|
|
|
|
|
|
//public static void SetValue<TClass>(TClass obj)
|
|
|
//{
|
|
|
// var properties = GetField(obj);
|
|
|
// properties[0].SetValue(obj, "", null);
|
|
|
//}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取公共属性的值。
|
|
|
/// <para>忽略索引。如:public char this[int index] { get; }</para>
|
|
|
/// <para>忽略不可读的属性</para>
|
|
|
/// </summary>
|
|
|
public static Dictionary<string, object> GetPublicPropertyValues<TClass>(TClass obj)
|
|
|
{
|
|
|
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 设置指定对象的值为values
|
|
|
/// <para>忽略索引。如:public char this[int index] { get; }</para>
|
|
|
/// <para>忽略不可写的属性</para>
|
|
|
/// </summary>
|
|
|
public static void SetValues<TClass, TValue>(TClass obj, Dictionary<string, TValue> 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("未处理");
|
|
|
}
|
|
|
}
|
|
|
}
|