#if NET20 || NET30 || !NET_4_6 // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Generic; using System.Collections.ObjectModel; using System.Dynamic.Utils; using System.Reflection; using LinqInternal.Collections; namespace System.Linq.Expressions.Reimplement { /// /// Represents initializing members of a member of a newly created object. /// /// /// Use the factory methods to create a . /// The value of the property of a object is . /// public sealed class MemberMemberBinding : MemberBinding { private readonly ReadOnlyCollection _bindings; internal MemberMemberBinding(MemberInfo member, ReadOnlyCollection bindings) #pragma warning disable CS0618 // El tipo o el miembro est醤 obsoletos : base(MemberBindingType.MemberBinding, member) #pragma warning restore CS0618 // El tipo o el miembro est醤 obsoletos { _bindings = bindings; } /// /// Gets the bindings that describe how to initialize the members of a member. /// public ReadOnlyCollection Bindings { get { return _bindings; } } /// /// Creates a new expression that is like this one, but using the /// supplied children. If all of the children are the same, it will /// return this expression. /// /// The property of the result. /// This expression if no children changed, or an expression with the updated children. public MemberMemberBinding Update(IEnumerable bindings) { if (bindings == Bindings) { return this; } return Expression.MemberBind(Member, bindings); } } public partial class Expression { /// /// Creates a that represents the recursive initialization of members of a field or property. /// /// The to set the property equal to. /// An array of objects to use to populate the collection. /// A that has the property equal to and the and properties set to the specified values. public static MemberMemberBinding MemberBind(MemberInfo member, params MemberBinding[] bindings) { ContractUtils.RequiresNotNull(member, "member"); ContractUtils.RequiresNotNull(bindings, "bindings"); return MemberBind(member, (IEnumerable)bindings); } /// /// Creates a that represents the recursive initialization of members of a field or property. /// /// The to set the property equal to. /// An that contains objects to use to populate the collection. /// A that has the property equal to and the and properties set to the specified values. public static MemberMemberBinding MemberBind(MemberInfo member, IEnumerable bindings) { ContractUtils.RequiresNotNull(member, "member"); ContractUtils.RequiresNotNull(bindings, "bindings"); var roBindings = bindings.ToReadOnly(); Type memberType; ValidateGettableFieldOrPropertyMember(member, out memberType); ValidateMemberInitArgs(memberType, roBindings); return new MemberMemberBinding(member, roBindings); } /// /// Creates a that represents the recursive initialization of members of a member that is accessed by using a property accessor method. /// /// The that represents a property accessor method. /// An that contains objects to use to populate the collection. /// /// A that has the property equal to , /// the Member property set to the that represents the property accessed in , /// and properties set to the specified values. /// public static MemberMemberBinding MemberBind(MethodInfo propertyAccessor, params MemberBinding[] bindings) { ContractUtils.RequiresNotNull(propertyAccessor, "propertyAccessor"); return MemberBind(GetProperty(propertyAccessor), bindings); } /// /// Creates a that represents the recursive initialization of members of a member that is accessed by using a property accessor method. /// /// The that represents a property accessor method. /// An that contains objects to use to populate the collection. /// /// A that has the property equal to , /// the Member property set to the that represents the property accessed in , /// and properties set to the specified values. /// public static MemberMemberBinding MemberBind(MethodInfo propertyAccessor, IEnumerable bindings) { ContractUtils.RequiresNotNull(propertyAccessor, "propertyAccessor"); return MemberBind(GetProperty(propertyAccessor), bindings); } private static void ValidateGettableFieldOrPropertyMember(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.CanRead) { throw Error.PropertyDoesNotHaveGetter(pi); } memberType = pi.PropertyType; } else { memberType = fi.FieldType; } } private static void ValidateMemberInitArgs(Type type, ReadOnlyCollection bindings) { var n = bindings.Count; for (var i = 0; i < n; i++) { var b = bindings[i]; ContractUtils.RequiresNotNull(b, "bindings"); if (!b.Member.DeclaringType.IsAssignableFrom(type)) { throw Error.NotAMemberOfType(b.Member.Name, type); } } } } } #endif