/// <summary> /// 获取属性值 /// </summary> /// <param name="obj">对象</param> /// <param name="index">检索</param> /// <returns></returns> public Object GetValue(Object obj, Object[] index) { if (getHandler != null) { return(getHandler(obj, index)); } Int32 moduleKey = info.Module.GetHashCode(); Int32 handlerKey = info.MetadataToken; getHandler = DynamicCacheFactory <DynamicPropertyGetHandler> .Caches .GetOrAdd(moduleKey, innerModuleKey => new ConcurrentDictionary <Int32, DynamicPropertyGetHandler>()) .GetOrAdd(handlerKey, innerHandlerKey => DynamicMethodFactory.CreateGetHandler(type, info)); return(getHandler(obj, index)); }
/// <summary> /// 创建动态属性取值的委托 /// </summary> /// <returns>动态属性取值的委托</returns> /// <param name="property">属性</param> public static DynamicPropertyGetHandler CreateDynamicPropertyGetHandler(PropertyInfo property) { // 如果缓存中存在 if (dynamicPropertyGetHandlers.ContainsKey(property)) { return(dynamicPropertyGetHandlers[property]); } #region Emit 由于老是有安全性问题,使用 Expression 替代 // DynamicMethod method = new DynamicMethod( string.Format( "DynamicPropertyGet{0}", Guid.NewGuid() ), typeof( object ), new[] { typeof( object ) }, true ); // // ILGenerator gen = method.GetILGenerator(); // // gen.DeclareLocal( typeof( object ) ); // // gen.Emit( OpCodes.Ldarg_0 ); // gen.Emit( OpCodes.Castclass, property.DeclaringType ); // // gen.EmitCall( OpCodes.Call, property.GetGetMethod(), null ); // // if( property.GetGetMethod().ReturnType.IsValueType ) // { // gen.Emit( OpCodes.Box, property.GetGetMethod().ReturnType ); // } // // gen.Emit( OpCodes.Stloc_0 ); // gen.Emit( OpCodes.Ldloc_0 ); // // gen.Emit( OpCodes.Ret ); // // DynamicPropertyGetHandler handler = (DynamicPropertyGetHandler)method.CreateDelegate( typeof( DynamicPropertyGetHandler ) ); #endregion var instance = Expression.Parameter(typeof(object)); var castInstance = Expression.Convert(instance, property.DeclaringType); var value = Expression.Property(castInstance, property); var castValue = Expression.Convert(value, typeof(object)); DynamicPropertyGetHandler handler = Expression.Lambda <DynamicPropertyGetHandler>(castValue, instance).Compile(); dynamicPropertyGetHandlers.Add(property, handler); return(handler); }
/// <summary> /// 创建动态属性取值的委托 /// </summary> /// <returns>动态属性取值的委托</returns> /// <param name="property">属性</param> public static DynamicPropertyGetHandler CreateDynamicPropertyGetHandler(PropertyInfo property) { // 如果缓存中存在 if (dynamicPropertyGetHandlers.ContainsKey(property)) { return(dynamicPropertyGetHandlers[property]); } DynamicMethod method = new DynamicMethod(string.Format("DynamicPropertyGet{0}", Guid.NewGuid()), typeof(object), new[] { typeof(object) }, true); ILGenerator gen = method.GetILGenerator(); gen.DeclareLocal(typeof(object)); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Castclass, property.DeclaringType); gen.EmitCall(OpCodes.Call, property.GetGetMethod(), null); if (property.GetGetMethod().ReturnType.IsValueType) { gen.Emit(OpCodes.Box, property.GetGetMethod().ReturnType); } gen.Emit(OpCodes.Stloc_0); gen.Emit(OpCodes.Ldloc_0); gen.Emit(OpCodes.Ret); DynamicPropertyGetHandler handler = (DynamicPropertyGetHandler)method.CreateDelegate(typeof(DynamicPropertyGetHandler)); //DynamicPropertyGetHandler handler = (DynamicPropertyGetHandler)Delegate.CreateDelegate(typeof(DynamicPropertyGetHandler), newType.GetMethod("DynamicPropertyGet")); dynamicPropertyGetHandlers.Add(property, handler); return(handler); }
/// <summary> /// 根据PropertyInfo和对象获取对应值 /// </summary> /// <param name="propertyInfo"></param> /// <param name="obj">PropertyInfo所在对象</param> /// <param name="index">如果是一个索引Property,请指定索引值,否则,指定null</param> /// <returns>返回值</returns> public static object GetValue(PropertyInfo propertyInfo, object obj, object[] index) { DynamicPropertyGetHandler handler = null; int key = propertyInfo.MetadataToken; #if Server handler = CachePropertyGet.GetOrAdd(key, new Func <int, DynamicPropertyGetHandler>((i) => CreateGetHandler(propertyInfo))); #else lock (CachePropertyGet) { if (CachePropertyGet.ContainsKey(key)) { handler = CachePropertyGet[key]; } else { handler = CreateGetHandler(propertyInfo); CachePropertyGet.Add(key, handler); } } #endif return(handler(obj, index)); }
/// <summary> /// 使用 Emit 方式获取属性值 /// </summary> /// <param name="property"></param> /// <param name="instance"></param> /// <returns></returns> public static object EmitGetValue(this PropertyInfo property, object instance) { DynamicPropertyGetHandler handler = DynamicHelper.CreateDynamicPropertyGetHandler(property); return(handler(instance)); }