/// <summary> /// Creates a property setter method with Lambda Expressions. /// </summary> /// <param name="propertyInfo">The property info.</param> private static Action <T, object> CreatePropertySetter(System.Reflection.PropertyInfo propertyInfo) { // check cache to avoid creating another method string cacheKey = "setter." + propertyInfo.GetHashCode(); object cache; if (internalCache.TryGetValue(cacheKey, out cache)) { return((Action <T, object>)cache); } // create method var name = propertyInfo.Name; var propType = propertyInfo.PropertyType; var sourceType = Expression.Parameter(typeof(T)); var argument = Expression.Parameter(typeof(object), name); var propExp = Expression.Property(sourceType, name); var castToObject = Expression.Convert(argument, propType); var method = Expression.Lambda <Action <T, object> > (Expression.Assign(propExp, castToObject), sourceType, argument).Compile(); // add to cache and return internalCache.TryAdd(cacheKey, method); return(method); }
//static object setLock=new object(); /// <summary> /// Fast setter. aprox 8x faster than simple Reflection /// </summary> /// <param name="a"></param> /// <param name="value"></param> public static void SetValueFast(this PropertyInfo p, object a, object value) { Setter inv = null; if (_cache == null) { _cache = new ConcurrentDictionary <int, Setter>(); } var key = p.GetHashCode(); if (!_cache.TryGetValue(key, out inv)) { var mi = p.GetSetMethod(); DynamicMethod met = new DynamicMethod("set_" + key, typeof(void), new[] { typeof(object), typeof(object) }, typeof(ObjectExtend).Module, true); var il = met.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); //instance il.Emit(OpCodes.Ldarg_1); //value if (p.PropertyType.IsValueType) { il.Emit(OpCodes.Unbox_Any, p.PropertyType); } il.Emit(OpCodes.Call, mi); il.Emit(OpCodes.Ret); inv = (Setter)met.CreateDelegate(typeof(Setter)); _cache.TryAdd(key, inv); } inv(a, value); }
/// <summary> /// Fast getter. aprox 5x faster than simple Reflection, aprox. 10x slower than manual get /// </summary> /// <param name="a"></param> public static object GetValueFast(this PropertyInfo p, object a) { Func <object, object> inv = null; if (_cacheGet == null) { _cacheGet = new ConcurrentDictionary <int, Func <object, object> >(); } var key = p.GetHashCode(); if (!_cacheGet.TryGetValue(key, out inv)) { var mi = p.GetGetMethod(); DynamicMethod met = new DynamicMethod("get_" + key, typeof(object), new[] { typeof(object) }, typeof(ObjectExtend).Module, true); var il = met.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); //instance il.Emit(OpCodes.Call, mi); //call getter if (p.PropertyType.IsValueType) { il.Emit(OpCodes.Box, p.PropertyType); } il.Emit(OpCodes.Ret); inv = (Func <object, object>)met.CreateDelegate(Expression.GetFuncType(typeof(object), typeof(object))); _cacheGet.TryAdd(key, inv); } return(inv(a)); }
static StackObject *GetHashCode_26(ILIntepreter __intp, StackObject *__esp, IList <object> __mStack, CLRMethod __method, bool isNewObj) { ILRuntime.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain; StackObject *ptr_of_this_method; StackObject *__ret = ILIntepreter.Minus(__esp, 1); ptr_of_this_method = ILIntepreter.Minus(__esp, 1); System.Reflection.PropertyInfo instance_of_this_method = (System.Reflection.PropertyInfo) typeof(System.Reflection.PropertyInfo).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack)); __intp.Free(ptr_of_this_method); var result_of_this_method = instance_of_this_method.GetHashCode(); __ret->ObjectType = ObjectTypes.Integer; __ret->Value = result_of_this_method; return(__ret + 1); }
/// <summary> /// Creates a property getter method with Lambda Expressions. /// </summary> /// <param name="propertyInfo">The property info.</param> private static Func <T, object> CreatePropertyGetter(System.Reflection.PropertyInfo propertyInfo) { // check cache to avoid creating another method string cacheKey = "getter." + propertyInfo.GetHashCode(); object cache; if (internalCache.TryGetValue(cacheKey, out cache)) { return((Func <T, object>)cache); } // create method var name = propertyInfo.Name; var source = Expression.Parameter(typeof(T)); var method = Expression.Lambda <Func <T, object> >(Expression.Convert(Expression.Property(source, name), typeof(object)), source).Compile(); // add to cache and return internalCache.TryAdd(cacheKey, method); return(method); }
GetCachedSetPropertyHandlerDelegate(Type type, PropertyInfo propertyInfo) { int intCachedKey = propertyInfo.GetHashCode();//type.ToString() + "|P|" + propertyInfo.Name; if (_propertySetDelegates.ContainsKey(intCachedKey)) return (SetHandler)_propertySetDelegates[intCachedKey]; SetHandler returnValue = CreateSetHandler(type, propertyInfo); lock (_propertySetDelegates) { _propertySetDelegates[intCachedKey] = returnValue; } return returnValue; }
/// <summary> /// Implement a property with getter/setter that relies on a private backup field. /// This is useful only to provide a temporary implementation of abstract properties that would be generated in a second time (this does not /// provide more than auto implemented properties available in C# 3.0 and later. /// </summary> /// <param name="tB">The <see cref="TypeBuilder"/> for the new type.</param> /// <param name="property">The property to implement.</param> /// <param name="isVirtual">Defaults to false: the method is sealed. True to keep the method virtual. </param> /// <returns>The <see cref="PropertyBuilder"/> to enable, for instance, creation of custom attributes on the property.</returns> public static PropertyBuilder ImplementStubProperty( TypeBuilder tB, PropertyInfo property, bool isVirtual = false ) { if( tB == null ) throw new ArgumentNullException( "tB" ); if( property == null ) throw new ArgumentNullException( "property" ); FieldBuilder backField = tB.DefineField( "_" + property.Name + property.GetHashCode(), property.PropertyType, FieldAttributes.Private ); MethodInfo getMethod = property.GetMethod; MethodBuilder mGet = null; if( getMethod != null ) { MethodAttributes mA = getMethod.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.VtableLayoutMask); if( isVirtual ) mA |= MethodAttributes.Virtual; mGet = tB.DefineMethod( getMethod.Name, mA, property.PropertyType, Type.EmptyTypes ); ILGenerator g = mGet.GetILGenerator(); g.LdArg( 0 ); g.Emit( OpCodes.Ldfld, backField ); g.Emit( OpCodes.Ret ); } MethodInfo setMethod = property.SetMethod; MethodBuilder mSet = null; if( setMethod != null ) { MethodAttributes mA = setMethod.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.VtableLayoutMask); if( isVirtual ) mA |= MethodAttributes.Virtual; mSet = tB.DefineMethod( setMethod.Name, mA, typeof( void ), new[] { property.PropertyType } ); ILGenerator g = mSet.GetILGenerator(); g.LdArg( 0 ); g.LdArg( 1 ); g.Emit( OpCodes.Stfld, backField ); g.Emit( OpCodes.Ret ); } PropertyBuilder p = tB.DefineProperty( property.Name, property.Attributes, property.PropertyType, Type.EmptyTypes ); if( mGet != null ) p.SetGetMethod( mGet ); if( mSet != null ) p.SetSetMethod( mSet ); return p; }