#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 the initialization of a list. /// public sealed class ElementInit : IArgumentProvider { private readonly MethodInfo _addMethod; private readonly ReadOnlyCollection _arguments; internal ElementInit(MethodInfo addMethod, ReadOnlyCollection arguments) { _addMethod = addMethod; _arguments = arguments; } /// /// Gets the used to add elements to the object. /// public MethodInfo AddMethod { get { return _addMethod; } } /// /// Gets the list of elements to be added to the object. /// public ReadOnlyCollection Arguments { get { return _arguments; } } public Expression GetArgument(int index) { return _arguments[index]; } public int ArgumentCount { get { return _arguments.Count; } } /// /// Creates a representation of the node. /// /// A representation of the node. public override string ToString() { return ExpressionStringBuilder.ElementInitBindingToString(this); } /// /// 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 ElementInit Update(IEnumerable arguments) { if (arguments == Arguments) { return this; } return Expression.ElementInit(AddMethod, arguments); } } public partial class Expression { /// /// Creates an ElementInit expression that represents the initialization of a list. /// /// The for the list's Add method. /// An array containing the Expressions to be used to initialize the list. /// The created ElementInit expression. public static ElementInit ElementInit(MethodInfo addMethod, params Expression[] arguments) { return ElementInit(addMethod, arguments as IEnumerable); } /// /// Creates an ElementInit expression that represents the initialization of a list. /// /// The for the list's Add method. /// An containing elements to initialize the list. /// The created ElementInit expression. public static ElementInit ElementInit(MethodInfo addMethod, IEnumerable arguments) { ContractUtils.RequiresNotNull(addMethod, "addMethod"); ContractUtils.RequiresNotNull(arguments, "arguments"); var argumentsReadOnly = arguments.ToReadOnly(); RequiresCanRead(argumentsReadOnly, "arguments"); ValidateElementInitAddMethodInfo(addMethod); ValidateArgumentTypes(addMethod, ExpressionType.Call, ref argumentsReadOnly); return new ElementInit(addMethod, argumentsReadOnly); } private static void ValidateElementInitAddMethodInfo(MethodInfo addMethod) { ValidateMethodInfo(addMethod); var pis = addMethod.GetParameters(); if (pis.Length == 0) { throw Error.ElementInitializerMethodWithZeroArgs(); } if (!addMethod.Name.Equals("Add", StringComparison.OrdinalIgnoreCase)) { throw Error.ElementInitializerMethodNotAdd(); } if (addMethod.IsStatic) { throw Error.ElementInitializerMethodStatic(); } foreach (var pi in pis) { if (pi.ParameterType.IsByRef) { throw Error.ElementInitializerMethodNoRefOutParam(pi.Name, addMethod.Name); } } } } } #endif