Exemple #1
0
        public static GenSetter CreateSetMethod(PropertyInfo pi)
        {
            Type   classType = typeof(T);
            Type   propType  = pi.PropertyType;
            string propName  = pi.Name;

            Dictionary <Type, Dictionary <string, GenSetter> > i1 = null;

            if (dSets.TryGetValue(classType, out i1))
            {
                Dictionary <string, GenSetter> i2 = null;
                if (i1.TryGetValue(propType, out i2))
                {
                    GenSetter i3 = null;
                    if (i2.TryGetValue(propName, out i3))
                    {
                        return(i3);
                    }
                }
            }

            //If there is no setter, return nothing
            MethodInfo setMethod = pi.GetSetMethod();

            if (setMethod == null)
            {
                return(null);
            }

            //Create dynamic method
            Type[] arguments = new Type[2] {
                classType, typeof(object)
            };

            DynamicMethod setter    = new DynamicMethod(String.Concat("_Set", pi.Name, "_"), typeof(void), arguments, classType);
            ILGenerator   generator = setter.GetILGenerator();

            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Castclass, classType);
            generator.Emit(OpCodes.Ldarg_1);

            if (propType.IsClass)
            {
                generator.Emit(OpCodes.Castclass, propType);
            }
            else
            {
                generator.Emit(OpCodes.Unbox_Any, propType);
            }

            generator.EmitCall(OpCodes.Callvirt, setMethod, null);
            generator.Emit(OpCodes.Ret);

            //Create the delegate and return it
            GenSetter genSetter = (GenSetter)setter.CreateDelegate(typeof(GenSetter));

            Dictionary <Type, Dictionary <string, GenSetter> > tempDict = null;
            Dictionary <string, GenSetter> tempPropDict = null;

            if (!dSets.ContainsKey(classType))
            {
                tempPropDict = new Dictionary <string, GenSetter>();
                tempPropDict.Add(propName, genSetter);
                tempDict = new Dictionary <Type, Dictionary <string, GenSetter> >();
                tempDict.Add(propType, tempPropDict);
                dSets.Add(classType, tempDict);
            }
            else
            {
                if (!dSets[classType].ContainsKey(propType))
                {
                    tempPropDict = new Dictionary <string, GenSetter>();
                    tempPropDict.Add(propName, genSetter);
                    dSets[classType].Add(propType, tempPropDict);
                }
                else
                {
                    if (!dSets[classType][propType].ContainsKey(propName))
                    {
                        dSets[classType][propType].Add(propName, genSetter);
                    }
                }
            }

            return(genSetter);
        }
        public static GenSetter CreateSetMethod(PropertyInfo pi)
        {
            //Create the locals needed.

            Type classType = typeof(T);

            Type returnType = typeof(K);

            string propertyName = pi.Name;



            //Let’s return the cached delegate if we have one.

            if (dSets.ContainsKey(classType))
            {
                if (dSets[classType].ContainsKey(returnType))
                {
                    if (dSets[classType][returnType].ContainsKey(propertyName))
                    {
                        return(dSets[classType][returnType][propertyName]);
                    }
                }
            }



            //If there is no setter, return nothing

            MethodInfo setMethod = pi.GetSetMethod();

            if (setMethod == null)
            {
                return(null);
            }



            //Create dynamic method

            Type[] arguments = new Type[2];

            arguments[0] = typeof(T);

            arguments[1] = typeof(K);



            DynamicMethod setter = new DynamicMethod(

                String.Concat("_Set", pi.Name, "_"),

                typeof(void),

                arguments,

                pi.DeclaringType);

            ILGenerator gen = setter.GetILGenerator();

            gen.Emit(OpCodes.Ldarg_0);

            gen.Emit(OpCodes.Castclass, pi.DeclaringType);

            gen.Emit(OpCodes.Ldarg_1);



            if (pi.PropertyType.IsClass)
            {
                gen.Emit(OpCodes.Castclass, pi.PropertyType);
            }



            gen.EmitCall(OpCodes.Callvirt, setMethod, null);

            gen.Emit(OpCodes.Ret);



            //Create the delegate

            GenSetter genSetter = (GenSetter)setter.CreateDelegate(typeof(GenSetter));



            //Cache the delegate for future use.

            Dictionary <Type, Dictionary <string, GenSetter> > tempDict = null;

            Dictionary <string, GenSetter> tempPropDict = null;

            if (!dSets.ContainsKey(classType))
            {
                tempPropDict = new Dictionary <string, GenSetter>();

                tempPropDict.Add(propertyName, genSetter);

                tempDict = new Dictionary <Type, Dictionary <string, GenSetter> >();

                tempDict.Add(returnType, tempPropDict);

                dSets.Add(classType, tempDict);
            }

            else
            {
                if (!dSets[classType].ContainsKey(returnType))
                {
                    tempPropDict = new Dictionary <string, GenSetter>();

                    tempPropDict.Add(propertyName, genSetter);

                    dSets[classType].Add(returnType, tempPropDict);
                }

                else
                {
                    if (!dSets[classType][returnType].ContainsKey(propertyName))
                    {
                        dSets[classType][returnType].Add(propertyName, genSetter);
                    }
                }
            }

            //Return delegate to the caller.

            return(genSetter);
        }