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
{
///
/// 检查输入值是否为空
///
///
///
static bool isNullOrEmpty(object val)
{
if (val == null) return true;
if (val.ToString() == "") return true;
return false;
}
/// Delegate to set an arbitrary property at runtime.
/// the object instance whose property will be modified.
///
public delegate void FastPropertySetHandler(object target, object parameter);
///
/// 用于存放SetPropertySetter的Dictionary
///
private static Dictionary dictSetter = new Dictionary();
///
/// 快速设置成员属性
///
///
///
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;
}
}
/// Emits the cast to a reference, unboxing if needed.
/// The MSIL generator.
/// The type to cast.
private static void EmitCastToReference(ILGenerator ilGenerator, System.Type type)
{
if (type.IsValueType)
{
ilGenerator.Emit(OpCodes.Unbox_Any, type);
}
else
{
ilGenerator.Emit(OpCodes.Castclass, type);
}
}
///
/// 根据数据类型将指定数据进行相应转换
///
///
///
///
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))
{
value = Convert.ToUInt16(value);
}
else if (type == typeof(System.Nullable))
{
value = Convert.ToUInt32(value);
}
else if (type == typeof(System.Nullable))
{
value = Convert.ToUInt64(value);
}
else if (type == typeof(System.Nullable))
{
value = Convert.ToInt32(value);
}
else if (type == typeof(System.Nullable))
{
value = Convert.ToInt64(value);
}
else if (type == typeof(System.Nullable))
{
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;
}
///
/// 设置属性值
///
///
///
///
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);
}
}
}
///
/// 设置属性值
///
///
///
///
public static void SetPropertyValue(object obj, string propertyName, object value)
{
SetPropertyValue(obj.GetType(), obj, propertyName, value);
}
///
/// 设置属性值
///
///
///
///
///
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;
}
}
}