public override bool Equals(object obj) { if (obj is ReflectionPropertyCacheKey) { ReflectionPropertyCacheKey k = (ReflectionPropertyCacheKey)obj; return(k.t == t && k.propName == propName); } return(base.Equals(obj)); }
internal void SetObjectProperty(Type t, object o, string propName, IValueFactory factory, IValueInitInfo valueInfo) { if (ReflectionCacheEnabled) { ReflectionPropertyCacheKey cacheKey = new ReflectionPropertyCacheKey(t, propName); ReflectionPropertyCacheValue cacheValue; if (!propertyInfoCache.TryGetValue(cacheKey, out cacheValue)) { System.Reflection.PropertyInfo propInfo = t.GetProperty(propName); if (propInfo == null) { throw new MissingMethodException(t.ToString(), propName); } MethodInfo setMethodInfo = propInfo.GetSetMethod(false); DynamicMethod setDynMethod = new DynamicMethod(String.Empty, typeof(void), new Type[] { typeof(object), typeof(object) }, t, true); ILGenerator setGenerator = setDynMethod.GetILGenerator(); setGenerator.Emit(OpCodes.Ldarg_0); setGenerator.Emit(OpCodes.Ldarg_1); if (setMethodInfo.GetParameters()[0].ParameterType.IsValueType) { setGenerator.Emit(OpCodes.Unbox_Any, setMethodInfo.GetParameters()[0].ParameterType); } setGenerator.Emit(OpCodes.Call, setMethodInfo); setGenerator.Emit(OpCodes.Ret); cacheValue = new ReflectionPropertyCacheValue( (PropertySetHandler)setDynMethod.CreateDelegate(typeof(PropertySetHandler)), propInfo.PropertyType); // despite the fact Dictionary is thread safe, for some reason sometimes exceptions are thrown without extra lock lock (propertyInfoCache) { propertyInfoCache[cacheKey] = cacheValue; } } object value = valueInfo.GetValue(factory, cacheValue.PropertyType); cacheValue.SetHandler(o, value); } else { System.Reflection.PropertyInfo propInfo = t.GetProperty(propName); if (propInfo == null) { throw new MissingMethodException(t.ToString(), propName); } propInfo.SetValue(o, valueInfo.GetValue(factory, propInfo.PropertyType), null); } }