314 lines
10 KiB
C#
314 lines
10 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Data;
|
|||
|
using System.Data.Common;
|
|||
|
using System.Linq;
|
|||
|
using System.Reflection;
|
|||
|
using System.Reflection.Emit;
|
|||
|
using System.Text;
|
|||
|
|
|||
|
namespace SqlSugar
|
|||
|
{
|
|||
|
|
|||
|
public static class ReflectionExtensions
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 检查输入值是否为空
|
|||
|
/// </summary>
|
|||
|
/// <param name="val"></param>
|
|||
|
/// <returns></returns>
|
|||
|
static bool isNullOrEmpty(object val)
|
|||
|
{
|
|||
|
if (val == null) return true;
|
|||
|
if (val.ToString() == "") return true;
|
|||
|
return false;
|
|||
|
}
|
|||
|
/// <summary>Delegate to set an arbitrary property at runtime.</summary>
|
|||
|
/// <param name="target">the object instance whose property will be modified.</param>
|
|||
|
/// <param name="parameter"></param>
|
|||
|
public delegate void FastPropertySetHandler(object target, object parameter);
|
|||
|
/// <summary>
|
|||
|
/// 用于存放SetPropertySetter的Dictionary
|
|||
|
/// </summary>
|
|||
|
private static Dictionary<PropertyInfo, FastPropertySetHandler> dictSetter = new Dictionary<PropertyInfo, FastPropertySetHandler>();
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 快速设置成员属性
|
|||
|
/// </summary>
|
|||
|
/// <param name="propInfo"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public static FastPropertySetHandler GetPropertySetter(PropertyInfo propInfo)
|
|||
|
{
|
|||
|
lock (dictSetter)
|
|||
|
{
|
|||
|
if (dictSetter.ContainsKey(propInfo)) return dictSetter[propInfo];
|
|||
|
|
|||
|
// generates a dynamic method to generate a FastPropertySetHandler delegate
|
|||
|
DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, null, new Type[] { typeof(object), typeof(object) }, propInfo.DeclaringType.Module);
|
|||
|
|
|||
|
ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
|
|||
|
|
|||
|
// loads the object into the stack
|
|||
|
ilGenerator.Emit(OpCodes.Ldarg_0);
|
|||
|
|
|||
|
// loads the parameter from the stack
|
|||
|
ilGenerator.Emit(OpCodes.Ldarg_1);
|
|||
|
|
|||
|
// cast to the proper type (unboxing if needed)
|
|||
|
EmitCastToReference(ilGenerator, propInfo.PropertyType);
|
|||
|
|
|||
|
// calls the setter
|
|||
|
ilGenerator.EmitCall(OpCodes.Callvirt, propInfo.GetSetMethod(), null);
|
|||
|
|
|||
|
// terminates the call
|
|||
|
ilGenerator.Emit(OpCodes.Ret);
|
|||
|
|
|||
|
// converts the DynamicMethod to a FastPropertyGetHandler delegate to get the property
|
|||
|
FastPropertySetHandler setter = (FastPropertySetHandler)dynamicMethod.CreateDelegate(typeof(FastPropertySetHandler));
|
|||
|
|
|||
|
dictSetter.Add(propInfo, setter);
|
|||
|
|
|||
|
return setter;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>Emits the cast to a reference, unboxing if needed.</summary>
|
|||
|
/// <param name="ilGenerator">The MSIL generator.</param>
|
|||
|
/// <param name="type">The type to cast.</param>
|
|||
|
private static void EmitCastToReference(ILGenerator ilGenerator, System.Type type)
|
|||
|
{
|
|||
|
if (type.IsValueType)
|
|||
|
{
|
|||
|
ilGenerator.Emit(OpCodes.Unbox_Any, type);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ilGenerator.Emit(OpCodes.Castclass, type);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 根据数据类型将指定数据进行相应转换
|
|||
|
/// </summary>
|
|||
|
/// <param name="value"></param>
|
|||
|
/// <param name="type"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public static object ConvertForType(object value, Type type)
|
|||
|
{
|
|||
|
if (Convert.IsDBNull(value) || (value == null))
|
|||
|
{
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
string typeName = type.FullName.ToString();
|
|||
|
|
|||
|
if (type == typeof(System.Nullable<UInt16>))
|
|||
|
{
|
|||
|
value = Convert.ToUInt16(value);
|
|||
|
}
|
|||
|
else if (type == typeof(System.Nullable<UInt32>))
|
|||
|
{
|
|||
|
value = Convert.ToUInt32(value);
|
|||
|
}
|
|||
|
else if (type == typeof(System.Nullable<UInt64>))
|
|||
|
{
|
|||
|
value = Convert.ToUInt64(value);
|
|||
|
}
|
|||
|
else if (type == typeof(System.Nullable<Int32>))
|
|||
|
{
|
|||
|
value = Convert.ToInt32(value);
|
|||
|
}
|
|||
|
else if (type == typeof(System.Nullable<Int64>))
|
|||
|
{
|
|||
|
value = Convert.ToInt64(value);
|
|||
|
}
|
|||
|
else if (type == typeof(System.Nullable<DateTime>))
|
|||
|
{
|
|||
|
value = Convert.ToDateTime(value);
|
|||
|
}
|
|||
|
|
|||
|
switch (typeName)
|
|||
|
{
|
|||
|
case "System.String":
|
|||
|
if (!isNullOrEmpty(value))
|
|||
|
value = value.ToString();
|
|||
|
else
|
|||
|
value = string.Empty;
|
|||
|
break;
|
|||
|
case "System.Boolean":
|
|||
|
if (!isNullOrEmpty(value))
|
|||
|
value = Convert.ToBoolean(value);
|
|||
|
break;
|
|||
|
case "System.Int16":
|
|||
|
if (!isNullOrEmpty(value))
|
|||
|
value = Convert.ToInt16(value);
|
|||
|
break;
|
|||
|
case "System.Int32":
|
|||
|
if (!isNullOrEmpty(value))
|
|||
|
value = Convert.ToInt32(value);
|
|||
|
else
|
|||
|
value = 0;
|
|||
|
break;
|
|||
|
case "System.Int64":
|
|||
|
if (!isNullOrEmpty(value))
|
|||
|
value = Convert.ToInt64(value);
|
|||
|
else
|
|||
|
value = 0;
|
|||
|
break;
|
|||
|
case "System.Double":
|
|||
|
if (!isNullOrEmpty(value))
|
|||
|
value = Convert.ToDouble(value);
|
|||
|
else
|
|||
|
value = 0.00;
|
|||
|
break;
|
|||
|
case "System.Float":
|
|||
|
if (!isNullOrEmpty(value))
|
|||
|
value = Convert.ToDouble(value);
|
|||
|
else
|
|||
|
value = 0.00;
|
|||
|
break;
|
|||
|
case "System.Single":
|
|||
|
if (!isNullOrEmpty(value))
|
|||
|
value = Convert.ToSingle(value);
|
|||
|
|
|||
|
break;
|
|||
|
case "System.Decimal":
|
|||
|
if (!isNullOrEmpty(value))
|
|||
|
value = Convert.ToDecimal(value);
|
|||
|
else
|
|||
|
value = 0.00;
|
|||
|
break;
|
|||
|
case "System.DateTime":
|
|||
|
if (!isNullOrEmpty(value))
|
|||
|
value = Convert.ToDateTime(value);
|
|||
|
else
|
|||
|
value = DateTime.MinValue;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return value;
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 设置属性值
|
|||
|
/// </summary>
|
|||
|
/// <param name="obj"></param>
|
|||
|
/// <param name="property"></param>
|
|||
|
/// <param name="value"></param>
|
|||
|
public static void SetPropertyValue(object obj, PropertyInfo property, object value)
|
|||
|
{
|
|||
|
if (property.CanWrite)
|
|||
|
{
|
|||
|
var propertySetter = GetPropertySetter(property);
|
|||
|
value = ConvertForType(value, property.PropertyType);
|
|||
|
if (value != null)
|
|||
|
{
|
|||
|
if (property.PropertyType.BaseType.Name == "Enum")
|
|||
|
{
|
|||
|
propertySetter(obj, Enum.Parse(property.PropertyType, value.ToString()));
|
|||
|
}
|
|||
|
else
|
|||
|
propertySetter(obj, value);
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 设置属性值
|
|||
|
/// </summary>
|
|||
|
/// <param name="obj"></param>
|
|||
|
/// <param name="propertyName"></param>
|
|||
|
/// <param name="value"></param>
|
|||
|
public static void SetPropertyValue(object obj, string propertyName, object value)
|
|||
|
{
|
|||
|
SetPropertyValue(obj.GetType(), obj, propertyName, value);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 设置属性值
|
|||
|
/// </summary>
|
|||
|
/// <param name="type"></param>
|
|||
|
/// <param name="obj"></param>
|
|||
|
/// <param name="propertyName"></param>
|
|||
|
/// <param name="value"></param>
|
|||
|
public static void SetPropertyValue(Type type, object obj, string propertyName, object value)
|
|||
|
{
|
|||
|
PropertyInfo property = type.GetProperty(propertyName);
|
|||
|
if (property != null)
|
|||
|
{
|
|||
|
SetPropertyValue(obj, property, value);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static Type GetTypeInfo(this Type typeInfo)
|
|||
|
{
|
|||
|
return typeInfo;
|
|||
|
}
|
|||
|
|
|||
|
public static Type[] GetGenericArguments(this Type type)
|
|||
|
{
|
|||
|
var reval = type.GetTypeInfo().GetGenericArguments();
|
|||
|
return reval;
|
|||
|
}
|
|||
|
public static bool IsGenericType(this Type type)
|
|||
|
{
|
|||
|
var reval = type.GetTypeInfo().IsGenericType;
|
|||
|
return reval;
|
|||
|
}
|
|||
|
public static PropertyInfo[] GetProperties(this Type type)
|
|||
|
{
|
|||
|
var reval = type.GetTypeInfo().GetProperties();
|
|||
|
return reval;
|
|||
|
}
|
|||
|
public static PropertyInfo GetProperty(this Type type, string name)
|
|||
|
{
|
|||
|
var reval = type.GetTypeInfo().GetProperty(name);
|
|||
|
return reval;
|
|||
|
}
|
|||
|
|
|||
|
public static FieldInfo GetField(this Type type, string name)
|
|||
|
{
|
|||
|
var reval = type.GetTypeInfo().GetField(name);
|
|||
|
return reval;
|
|||
|
}
|
|||
|
|
|||
|
public static bool IsEnum(this Type type)
|
|||
|
{
|
|||
|
var reval = type.GetTypeInfo().IsEnum;
|
|||
|
return reval;
|
|||
|
}
|
|||
|
|
|||
|
public static MethodInfo GetMethod(this Type type, string name)
|
|||
|
{
|
|||
|
var reval = type.GetTypeInfo().GetMethod(name);
|
|||
|
return reval;
|
|||
|
}
|
|||
|
public static MethodInfo GetMethod(this Type type, string name, Type[] types)
|
|||
|
{
|
|||
|
var reval = type.GetTypeInfo().GetMethod(name, types);
|
|||
|
return reval;
|
|||
|
}
|
|||
|
public static ConstructorInfo GetConstructor(this Type type, Type[] types)
|
|||
|
{
|
|||
|
var reval = type.GetTypeInfo().GetConstructor(types);
|
|||
|
return reval;
|
|||
|
}
|
|||
|
|
|||
|
public static bool IsValueType(this Type type)
|
|||
|
{
|
|||
|
return type.GetTypeInfo().IsValueType;
|
|||
|
}
|
|||
|
|
|||
|
public static bool IsEntity(this Type type)
|
|||
|
{
|
|||
|
return type.GetTypeInfo().IsClass;
|
|||
|
}
|
|||
|
|
|||
|
public static Type ReflectedType(this MethodInfo method)
|
|||
|
{
|
|||
|
return method.ReflectedType;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|