public static GenericSetter CreateGenericSetter(Type type, MemberInfo memberInfo) { if (memberInfo == null) { throw new ArgumentNullException("propertyInfo"); } // if has no write if (memberInfo is PropertyInfo && (memberInfo as PropertyInfo).CanWrite == false) { return(null); } #if NET35 // do not use Expression in Structs (there is no Expression.Unbox in NET3.5) if (type.IsValueType) { // if member is property, use GetSetMethod if (memberInfo is PropertyInfo) { var setMethod = (memberInfo as PropertyInfo).GetSetMethod(); return((t, v) => setMethod.Invoke(t, new[] { v })); } else { return(null); // no field on Structs } } #endif var dataType = memberInfo is PropertyInfo ? (memberInfo as PropertyInfo).PropertyType : (memberInfo as FieldInfo).FieldType; var target = Expression.Parameter(typeof(object), "obj"); var value = Expression.Parameter(typeof(object), "val"); #if NET35 var castTarget = Expression.Convert(target, type); #else var castTarget = type.GetTypeInfo().IsValueType ? Expression.Unbox(target, type) : Expression.Convert(target, type); #endif var castValue = Expression.ConvertChecked(value, dataType); var accessor = memberInfo is PropertyInfo?Expression.Property(castTarget, memberInfo as PropertyInfo) : memberInfo is FieldInfo?Expression.Field(castTarget, memberInfo as FieldInfo) : null; #if NET35 var assign = ExpressionExtensions.Assign(accessor, castValue); #else var assign = Expression.Assign(accessor, castValue); #endif var conv = Expression.Convert(assign, typeof(object)); return(Expression.Lambda <GenericSetter>(conv, target, value).Compile()); }
public static GenericSetter CreateGenericSetter(Type type, MemberInfo memberInfo) { if (memberInfo == null) { throw new ArgumentNullException("propertyInfo"); } var fieldInfo = memberInfo as FieldInfo; var propertyInfo = memberInfo as PropertyInfo; // if is property and has no write if (memberInfo is PropertyInfo && propertyInfo.CanWrite == false) { return(null); } // if *Structs*, use direct reflection - net35 has no Expression.Unbox to cast target if (type.GetTypeInfo().IsValueType) { return(memberInfo is FieldInfo ? (GenericSetter)fieldInfo.SetValue : ((t, v) => propertyInfo.SetValue(t, v, null))); } var dataType = memberInfo is PropertyInfo ? propertyInfo.PropertyType : fieldInfo.FieldType; var target = Expression.Parameter(typeof(object), "obj"); var value = Expression.Parameter(typeof(object), "val"); var castTarget = Expression.Convert(target, type); var castValue = Expression.ConvertChecked(value, dataType); var accessor = memberInfo is PropertyInfo? Expression.Property(castTarget, propertyInfo) : Expression.Field(castTarget, fieldInfo); var assign = ExpressionExtensions.Assign(accessor, castValue); var conv = Expression.Convert(assign, typeof(object)); return(Expression.Lambda <GenericSetter>(conv, target, value).Compile()); }
public static GenericSetter CreateGenericSetter(Type type, MemberInfo memberInfo) { if (memberInfo == null) { throw new ArgumentNullException("propertyInfo"); } var fieldInfo = memberInfo as FieldInfo; var propertyInfo = memberInfo as PropertyInfo; // // if is property and has no write // hh: private setters if (memberInfo is PropertyInfo && propertyInfo.CanWrite == false) { PropertyInfo pi = null; var bt = type; do { bt = bt.GetTypeInfo().BaseType; if (bt == null) { break; } pi = bt.GetProperties(BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public).FirstOrDefault(x => x.Name == propertyInfo.Name); } while (bt != null && (pi == null || !pi.CanWrite)); if (pi == null) { return(null); } return((t, v) => pi.SetValue(t, v, null)); } // if *Structs*, use direct reflection - net35 has no Expression.Unbox to cast target if (type.GetTypeInfo().IsValueType) { return(memberInfo is FieldInfo ? (GenericSetter)fieldInfo.SetValue : ((t, v) => propertyInfo.SetValue(t, v, null))); } var dataType = memberInfo is PropertyInfo ? propertyInfo.PropertyType : fieldInfo.FieldType; var target = Expression.Parameter(typeof(object), "obj"); var value = Expression.Parameter(typeof(object), "val"); var castTarget = Expression.Convert(target, type); var castValue = Expression.ConvertChecked(value, dataType); var accessor = memberInfo is PropertyInfo? Expression.Property(castTarget, propertyInfo) : Expression.Field(castTarget, fieldInfo); var assign = ExpressionExtensions.Assign(accessor, castValue); var conv = Expression.Convert(assign, typeof(object)); return(Expression.Lambda <GenericSetter>(conv, target, value).Compile()); }