/// <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;
        }
Beispiel #7
0
        /// <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;
        }