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); }