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;
            }
        }
Esempio n. 2
0
        /// <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));
        }