private static void ValidateSettableFieldOrPropertyMember(MemberInfo member, out Type memberType) { var fi = member as FieldInfo; if (fi == null) { var pi = member as PropertyInfo; if (pi == null) { throw Error.ArgumentMustBeFieldInfoOrPropertInfo(); } if (!pi.CanWrite) { throw Error.PropertyDoesNotHaveSetter(pi); } memberType = pi.PropertyType; } else { memberType = fi.FieldType; } }
/// <summary> /// Creates a <see cref="MemberInitializer"/> binding the specified value to the given member. /// </summary> /// <param name="member">The <see cref="MemberInfo"/> for the member which is being assigned to.</param> /// <param name="expression">The value to be assigned to <paramref name="member"/>.</param> /// <returns>The created <see cref="MemberInitializer"/>.</returns> public static MemberInitializer MemberInitializer(MemberInfo member, Expression expression) { RequiresNotNull(member, nameof(member)); // // NB: System.Linq.Expressions fails to checks for static members in ValidateSettableFieldOrPropertyMember. // // class Foo { public static int Bar { get; set; } } // // Expression.Lambda<Func<Foo>>( // Expression.MemberInit( // Expression.New(typeof(Foo)), // Expression.Bind(typeof(Foo).GetProperty("Bar"), Expression.Constant(1)) // ) // ).Compile() // // throws 'System.Security.VerificationException: Operation could destabilize the runtime.' // // We add this check here. // Type memberType; switch (member) { case FieldInfo f: memberType = f.FieldType; if (f.IsStatic) { throw Error.MemberInitializerMemberMustNotBeStatic(member.Name); } break; case PropertyInfo p: memberType = p.PropertyType; var accessor = p.GetGetMethod(nonPublic: true) ?? p.GetSetMethod(nonPublic: true); if (accessor == null) { throw LinqError.PropertyDoesNotHaveAccessor(p); } if (accessor.IsStatic) { throw Error.MemberInitializerMemberMustNotBeStatic(member.Name); } if (p.GetIndexParameters().Length > 0) { throw Error.MemberInitializerMemberMustNotBeIndexer(member.Name); } break; default: throw LinqError.ArgumentMustBeFieldInfoOrPropertInfo(); } RequiresCanRead(expression, nameof(expression)); // // NB: We don't check here for an accessible setter in order to support anonymous types where // the getter is specified instead. // if (!memberType.IsAssignableFrom(expression.Type)) { throw LinqError.ArgumentTypesMustMatch(); } if (member.DeclaringType == null) { throw Error.NotAMemberOfAnyType(member); } ValidateType(member.DeclaringType); return(new MemberInitializer(member, expression)); }