1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
5 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
6 * copy of the license can be found in the License.html file at the root of this distribution. If
7 * you cannot locate the Apache License, Version 2.0, please send an email to
8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
9 * by the terms of the Apache License, Version 2.0.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
17 using System.Collections.Generic;
18 using System.Collections.ObjectModel;
19 using System.Diagnostics;
20 using System.Dynamic.Utils;
21 using System.Reflection;
22 using System.Runtime.CompilerServices;
25 namespace Microsoft.Scripting.Ast {
27 namespace System.Linq.Expressions {
30 /// Represents a call to either static or an instance method.
32 [DebuggerTypeProxy(typeof(Expression.MethodCallExpressionProxy))]
33 public class MethodCallExpression : Expression, IArgumentProvider {
34 private readonly MethodInfo _method;
36 internal MethodCallExpression(MethodInfo method) {
41 internal virtual Expression GetInstance() {
46 /// Returns the node type of this <see cref="Expression" />. (Inherited from <see cref="Expression" />.)
48 /// <returns>The <see cref="ExpressionType"/> that represents this expression.</returns>
49 public sealed override ExpressionType NodeType {
50 get { return ExpressionType.Call; }
54 /// Gets the static type of the expression that this <see cref="Expression" /> represents. (Inherited from <see cref="Expression"/>.)
56 /// <returns>The <see cref="Type"/> that represents the static type of the expression.</returns>
57 public sealed override Type Type {
58 get { return _method.ReturnType; }
62 /// Gets the <see cref="MethodInfo" /> for the method to be called.
64 public MethodInfo Method {
65 get { return _method; }
69 /// Gets the <see cref="Expression" /> that represents the instance
70 /// for instance method calls or null for static method cals.
72 public Expression Object {
73 get { return GetInstance(); }
77 /// Gets a collection of expressions that represent arguments to the method call.
79 public ReadOnlyCollection<Expression> Arguments {
80 get { return GetOrMakeArguments(); }
84 /// Creates a new expression that is like this one, but using the
85 /// supplied children. If all of the children are the same, it will
86 /// return this expression.
88 /// <param name="object">The <see cref="Object" /> property of the result.</param>
89 /// <param name="arguments">The <see cref="Arguments" /> property of the result.</param>
90 /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
91 public MethodCallExpression Update(Expression @object, IEnumerable<Expression> arguments) {
92 if (@object == Object && arguments == Arguments) {
95 return Expression.Call(@object, Method, arguments);
98 internal virtual ReadOnlyCollection<Expression> GetOrMakeArguments() {
99 throw ContractUtils.Unreachable;
103 /// Dispatches to the specific visit method for this node type.
105 protected internal override Expression Accept(ExpressionVisitor visitor) {
106 return visitor.VisitMethodCall(this);
110 /// Returns a new MethodCallExpression replacing the existing instance/args with the
111 /// newly provided instance and args. Arguments can be null to use the existing
114 /// This helper is provided to allow re-writing of nodes to not depend on the specific optimized
115 /// subclass of MethodCallExpression which is being used.
117 internal virtual MethodCallExpression Rewrite(Expression instance, IList<Expression> args) {
118 throw ContractUtils.Unreachable;
121 #region IArgumentProvider Members
123 Expression IArgumentProvider.GetArgument(int index) {
124 throw ContractUtils.Unreachable;
127 int IArgumentProvider.ArgumentCount {
128 get { throw ContractUtils.Unreachable; }
134 #region Specialized Subclasses
136 internal class MethodCallExpressionN : MethodCallExpression, IArgumentProvider {
137 private IList<Expression> _arguments;
139 public MethodCallExpressionN(MethodInfo method, IList<Expression> args)
144 Expression IArgumentProvider.GetArgument(int index) {
145 return _arguments[index];
148 int IArgumentProvider.ArgumentCount {
150 return _arguments.Count;
154 internal override ReadOnlyCollection<Expression> GetOrMakeArguments() {
155 return ReturnReadOnly(ref _arguments);
158 internal override MethodCallExpression Rewrite(Expression instance, IList<Expression> args) {
159 Debug.Assert(instance == null);
160 Debug.Assert(args == null || args.Count == _arguments.Count);
162 return Expression.Call(Method, args ?? _arguments);
166 internal class InstanceMethodCallExpressionN : MethodCallExpression, IArgumentProvider {
167 private IList<Expression> _arguments;
168 private readonly Expression _instance;
170 public InstanceMethodCallExpressionN(MethodInfo method, Expression instance, IList<Expression> args)
172 _instance = instance;
176 Expression IArgumentProvider.GetArgument(int index) {
177 return _arguments[index];
180 int IArgumentProvider.ArgumentCount {
182 return _arguments.Count;
186 internal override Expression GetInstance() {
190 internal override ReadOnlyCollection<Expression> GetOrMakeArguments() {
191 return ReturnReadOnly(ref _arguments);
194 internal override MethodCallExpression Rewrite(Expression instance, IList<Expression> args) {
195 Debug.Assert(instance != null);
196 Debug.Assert(args == null || args.Count == _arguments.Count);
198 return Expression.Call(instance, Method, args ?? _arguments);
202 internal class MethodCallExpression1 : MethodCallExpression, IArgumentProvider {
203 private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider
205 public MethodCallExpression1(MethodInfo method, Expression arg0)
210 Expression IArgumentProvider.GetArgument(int index) {
212 case 0: return ReturnObject<Expression>(_arg0);
213 default: throw new InvalidOperationException();
217 int IArgumentProvider.ArgumentCount {
223 internal override ReadOnlyCollection<Expression> GetOrMakeArguments() {
224 return ReturnReadOnly(this, ref _arg0);
227 internal override MethodCallExpression Rewrite(Expression instance, IList<Expression> args) {
228 Debug.Assert(instance == null);
229 Debug.Assert(args == null || args.Count == 1);
232 return Expression.Call(Method, args[0]);
235 return Expression.Call(Method, ReturnObject<Expression>(_arg0));
239 internal class MethodCallExpression2 : MethodCallExpression, IArgumentProvider {
240 private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider
241 private readonly Expression _arg1; // storage for the 2nd arg
243 public MethodCallExpression2(MethodInfo method, Expression arg0, Expression arg1)
249 Expression IArgumentProvider.GetArgument(int index) {
251 case 0: return ReturnObject<Expression>(_arg0);
252 case 1: return _arg1;
253 default: throw new InvalidOperationException();
257 int IArgumentProvider.ArgumentCount {
263 internal override ReadOnlyCollection<Expression> GetOrMakeArguments() {
264 return ReturnReadOnly(this, ref _arg0);
267 internal override MethodCallExpression Rewrite(Expression instance, IList<Expression> args) {
268 Debug.Assert(instance == null);
269 Debug.Assert(args == null || args.Count == 2);
272 return Expression.Call(Method, args[0], args[1]);
274 return Expression.Call(Method, ReturnObject<Expression>(_arg0), _arg1);
278 internal class MethodCallExpression3 : MethodCallExpression, IArgumentProvider {
279 private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider
280 private readonly Expression _arg1, _arg2; // storage for the 2nd - 3rd args.
282 public MethodCallExpression3(MethodInfo method, Expression arg0, Expression arg1, Expression arg2)
289 Expression IArgumentProvider.GetArgument(int index) {
291 case 0: return ReturnObject<Expression>(_arg0);
292 case 1: return _arg1;
293 case 2: return _arg2;
294 default: throw new InvalidOperationException();
298 int IArgumentProvider.ArgumentCount {
304 internal override ReadOnlyCollection<Expression> GetOrMakeArguments() {
305 return ReturnReadOnly(this, ref _arg0);
308 internal override MethodCallExpression Rewrite(Expression instance, IList<Expression> args) {
309 Debug.Assert(instance == null);
310 Debug.Assert(args == null || args.Count == 3);
313 return Expression.Call(Method, args[0], args[1], args[2]);
315 return Expression.Call(Method, ReturnObject<Expression>(_arg0), _arg1, _arg2);
319 internal class MethodCallExpression4 : MethodCallExpression, IArgumentProvider {
320 private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider
321 private readonly Expression _arg1, _arg2, _arg3; // storage for the 2nd - 4th args.
323 public MethodCallExpression4(MethodInfo method, Expression arg0, Expression arg1, Expression arg2, Expression arg3)
331 Expression IArgumentProvider.GetArgument(int index) {
333 case 0: return ReturnObject<Expression>(_arg0);
334 case 1: return _arg1;
335 case 2: return _arg2;
336 case 3: return _arg3;
337 default: throw new InvalidOperationException();
341 int IArgumentProvider.ArgumentCount {
347 internal override ReadOnlyCollection<Expression> GetOrMakeArguments() {
348 return ReturnReadOnly(this, ref _arg0);
351 internal override MethodCallExpression Rewrite(Expression instance, IList<Expression> args) {
352 Debug.Assert(instance == null);
353 Debug.Assert(args == null || args.Count == 4);
356 return Expression.Call(Method, args[0], args[1], args[2], args[3]);
358 return Expression.Call(Method, ReturnObject<Expression>(_arg0), _arg1, _arg2, _arg3);
362 internal class MethodCallExpression5 : MethodCallExpression, IArgumentProvider {
363 private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider
364 private readonly Expression _arg1, _arg2, _arg3, _arg4; // storage for the 2nd - 5th args.
366 public MethodCallExpression5(MethodInfo method, Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4)
375 Expression IArgumentProvider.GetArgument(int index) {
377 case 0: return ReturnObject<Expression>(_arg0);
378 case 1: return _arg1;
379 case 2: return _arg2;
380 case 3: return _arg3;
381 case 4: return _arg4;
382 default: throw new InvalidOperationException();
386 int IArgumentProvider.ArgumentCount {
392 internal override ReadOnlyCollection<Expression> GetOrMakeArguments() {
393 return ReturnReadOnly(this, ref _arg0);
396 internal override MethodCallExpression Rewrite(Expression instance, IList<Expression> args) {
397 Debug.Assert(instance == null);
398 Debug.Assert(args == null || args.Count == 5);
401 return Expression.Call(Method, args[0], args[1], args[2], args[3], args[4]);
404 return Expression.Call(Method, ReturnObject<Expression>(_arg0), _arg1, _arg2, _arg3, _arg4);
408 internal class InstanceMethodCallExpression2 : MethodCallExpression, IArgumentProvider {
409 private readonly Expression _instance;
410 private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider
411 private readonly Expression _arg1; // storage for the 2nd argument
413 public InstanceMethodCallExpression2(MethodInfo method, Expression instance, Expression arg0, Expression arg1)
415 Debug.Assert(instance != null);
417 _instance = instance;
422 Expression IArgumentProvider.GetArgument(int index) {
424 case 0: return ReturnObject<Expression>(_arg0);
425 case 1: return _arg1;
426 default: throw new InvalidOperationException();
430 int IArgumentProvider.ArgumentCount {
436 internal override Expression GetInstance() {
440 internal override ReadOnlyCollection<Expression> GetOrMakeArguments() {
441 return ReturnReadOnly(this, ref _arg0);
444 internal override MethodCallExpression Rewrite(Expression instance, IList<Expression> args) {
445 Debug.Assert(instance != null);
446 Debug.Assert(args == null || args.Count == 2);
449 return Expression.Call(instance, Method, args[0], args[1]);
451 return Expression.Call(instance, Method, ReturnObject<Expression>(_arg0), _arg1);
455 internal class InstanceMethodCallExpression3 : MethodCallExpression, IArgumentProvider {
456 private readonly Expression _instance;
457 private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider
458 private readonly Expression _arg1, _arg2; // storage for the 2nd - 3rd argument
460 public InstanceMethodCallExpression3(MethodInfo method, Expression instance, Expression arg0, Expression arg1, Expression arg2)
462 Debug.Assert(instance != null);
464 _instance = instance;
470 Expression IArgumentProvider.GetArgument(int index) {
472 case 0: return ReturnObject<Expression>(_arg0);
473 case 1: return _arg1;
474 case 2: return _arg2;
475 default: throw new InvalidOperationException();
479 int IArgumentProvider.ArgumentCount {
485 internal override Expression GetInstance() {
489 internal override ReadOnlyCollection<Expression> GetOrMakeArguments() {
490 return ReturnReadOnly(this, ref _arg0);
493 internal override MethodCallExpression Rewrite(Expression instance, IList<Expression> args) {
494 Debug.Assert(instance != null);
495 Debug.Assert(args == null || args.Count == 3);
498 return Expression.Call(instance, Method, args[0], args[1], args[2]);
500 return Expression.Call(instance, Method, ReturnObject<Expression>(_arg0), _arg1, _arg2);
506 public partial class Expression {
510 ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents a call to a static method that takes one argument.</summary>
511 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
512 ///<param name="method">A <see cref="T:System.Reflection.MethodInfo" /> to set the <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> property equal to.</param>
513 ///<param name="arg0">The <see cref="Expression" /> that represents the first argument.</param>
514 ///<exception cref="T:System.ArgumentNullException">
515 ///<paramref name="method" /> is null.</exception>
516 public static MethodCallExpression Call(MethodInfo method, Expression arg0) {
517 ContractUtils.RequiresNotNull(method, "method");
518 ContractUtils.RequiresNotNull(arg0, "arg0");
520 ParameterInfo[] pis = ValidateMethodAndGetParameters(null, method);
522 ValidateArgumentCount(method, ExpressionType.Call, 1, pis);
524 arg0 = ValidateOneArgument(method, ExpressionType.Call, arg0, pis[0]);
526 return new MethodCallExpression1(method, arg0);
529 ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents a call to a static method that takes two arguments.</summary>
530 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
531 ///<param name="method">A <see cref="T:System.Reflection.MethodInfo" /> to set the <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> property equal to.</param>
532 ///<param name="arg0">The <see cref="Expression" /> that represents the first argument.</param>
533 ///<param name="arg1">The <see cref="Expression" /> that represents the second argument.</param>
534 ///<exception cref="T:System.ArgumentNullException">
535 ///<paramref name="method" /> is null.</exception>
536 public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expression arg1) {
537 ContractUtils.RequiresNotNull(method, "method");
538 ContractUtils.RequiresNotNull(arg0, "arg0");
539 ContractUtils.RequiresNotNull(arg1, "arg1");
541 ParameterInfo[] pis = ValidateMethodAndGetParameters(null, method);
543 ValidateArgumentCount(method, ExpressionType.Call, 2, pis);
545 arg0 = ValidateOneArgument(method, ExpressionType.Call, arg0, pis[0]);
546 arg1 = ValidateOneArgument(method, ExpressionType.Call, arg1, pis[1]);
548 return new MethodCallExpression2(method, arg0, arg1);
551 ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents a call to a static method that takes three arguments.</summary>
552 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
553 ///<param name="method">A <see cref="T:System.Reflection.MethodInfo" /> to set the <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> property equal to.</param>
554 ///<param name="arg0">The <see cref="Expression" /> that represents the first argument.</param>
555 ///<param name="arg1">The <see cref="Expression" /> that represents the second argument.</param>
556 ///<param name="arg2">The <see cref="Expression" /> that represents the third argument.</param>
557 ///<exception cref="T:System.ArgumentNullException">
558 ///<paramref name="method" /> is null.</exception>
559 public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expression arg1, Expression arg2) {
560 ContractUtils.RequiresNotNull(method, "method");
561 ContractUtils.RequiresNotNull(arg0, "arg0");
562 ContractUtils.RequiresNotNull(arg1, "arg1");
563 ContractUtils.RequiresNotNull(arg2, "arg2");
565 ParameterInfo[] pis = ValidateMethodAndGetParameters(null, method);
567 ValidateArgumentCount(method, ExpressionType.Call, 3, pis);
569 arg0 = ValidateOneArgument(method, ExpressionType.Call, arg0, pis[0]);
570 arg1 = ValidateOneArgument(method, ExpressionType.Call, arg1, pis[1]);
571 arg2 = ValidateOneArgument(method, ExpressionType.Call, arg2, pis[2]);
573 return new MethodCallExpression3(method, arg0, arg1, arg2);
576 ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents a call to a static method that takes four arguments.</summary>
577 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
578 ///<param name="method">A <see cref="T:System.Reflection.MethodInfo" /> to set the <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> property equal to.</param>
579 ///<param name="arg0">The <see cref="Expression" /> that represents the first argument.</param>
580 ///<param name="arg1">The <see cref="Expression" /> that represents the second argument.</param>
581 ///<param name="arg2">The <see cref="Expression" /> that represents the third argument.</param>
582 ///<param name="arg3">The <see cref="Expression" /> that represents the fourth argument.</param>
583 ///<exception cref="T:System.ArgumentNullException">
584 ///<paramref name="method" /> is null.</exception>
585 public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expression arg1, Expression arg2, Expression arg3) {
586 ContractUtils.RequiresNotNull(method, "method");
587 ContractUtils.RequiresNotNull(arg0, "arg0");
588 ContractUtils.RequiresNotNull(arg1, "arg1");
589 ContractUtils.RequiresNotNull(arg2, "arg2");
590 ContractUtils.RequiresNotNull(arg3, "arg3");
592 ParameterInfo[] pis = ValidateMethodAndGetParameters(null, method);
594 ValidateArgumentCount(method, ExpressionType.Call, 4, pis);
596 arg0 = ValidateOneArgument(method, ExpressionType.Call, arg0, pis[0]);
597 arg1 = ValidateOneArgument(method, ExpressionType.Call, arg1, pis[1]);
598 arg2 = ValidateOneArgument(method, ExpressionType.Call, arg2, pis[2]);
599 arg3 = ValidateOneArgument(method, ExpressionType.Call, arg3, pis[3]);
601 return new MethodCallExpression4(method, arg0, arg1, arg2, arg3);
604 ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents a call to a static method that takes five arguments.</summary>
605 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
606 ///<param name="method">A <see cref="T:System.Reflection.MethodInfo" /> to set the <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> property equal to.</param>
607 ///<param name="arg0">The <see cref="Expression" /> that represents the first argument.</param>
608 ///<param name="arg1">The <see cref="Expression" /> that represents the second argument.</param>
609 ///<param name="arg2">The <see cref="Expression" /> that represents the third argument.</param>
610 ///<param name="arg3">The <see cref="Expression" /> that represents the fourth argument.</param>
611 ///<param name="arg4">The <see cref="Expression" /> that represents the fifth argument.</param>
612 ///<exception cref="T:System.ArgumentNullException">
613 ///<paramref name="method" /> is null.</exception>
614 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
615 public static MethodCallExpression Call(MethodInfo method, Expression arg0, Expression arg1, Expression arg2, Expression arg3, Expression arg4) {
616 ContractUtils.RequiresNotNull(method, "method");
617 ContractUtils.RequiresNotNull(arg0, "arg0");
618 ContractUtils.RequiresNotNull(arg1, "arg1");
619 ContractUtils.RequiresNotNull(arg2, "arg2");
620 ContractUtils.RequiresNotNull(arg3, "arg3");
621 ContractUtils.RequiresNotNull(arg4, "arg4");
623 ParameterInfo[] pis = ValidateMethodAndGetParameters(null, method);
625 ValidateArgumentCount(method, ExpressionType.Call, 5, pis);
627 arg0 = ValidateOneArgument(method, ExpressionType.Call, arg0, pis[0]);
628 arg1 = ValidateOneArgument(method, ExpressionType.Call, arg1, pis[1]);
629 arg2 = ValidateOneArgument(method, ExpressionType.Call, arg2, pis[2]);
630 arg3 = ValidateOneArgument(method, ExpressionType.Call, arg3, pis[3]);
631 arg4 = ValidateOneArgument(method, ExpressionType.Call, arg4, pis[4]);
633 return new MethodCallExpression5(method, arg0, arg1, arg2, arg3, arg4);
637 /// Creates a <see cref="MethodCallExpression" /> that represents a call to a static (Shared in Visual Basic) method.
639 /// <param name="method">The <see cref="MethodInfo" /> that represents the target method.</param>
640 /// <param name="arguments">The array of one or more of <see cref="Expression" /> that represents the call arguments.</param>
641 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
642 public static MethodCallExpression Call(MethodInfo method, params Expression[] arguments) {
643 return Call(null, method, arguments);
647 /// Creates a <see cref="MethodCallExpression" /> that represents a call to a static (Shared in Visual Basic) method.
649 /// <param name="method">The <see cref="MethodInfo" /> that represents the target method.</param>
650 /// <param name="arguments">A collection of <see cref="Expression" /> that represents the call arguments.</param>
651 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
652 public static MethodCallExpression Call(MethodInfo method, IEnumerable<Expression> arguments) {
653 return Call(null, method, arguments);
657 /// Creates a <see cref="MethodCallExpression" /> that represents a call to a method that takes no arguments.
659 /// <param name="instance">An <see cref="Expression" /> that specifies the instance for an instance call. (pass null for a static (Shared in Visual Basic) method).</param>
660 /// <param name="method">The <see cref="MethodInfo" /> that represents the target method.</param>
661 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
662 public static MethodCallExpression Call(Expression instance, MethodInfo method) {
663 return Call(instance, method, EmptyReadOnlyCollection<Expression>.Instance);
667 /// Creates a <see cref="MethodCallExpression" /> that represents a method call.
669 /// <param name="instance">An <see cref="Expression" /> that specifies the instance for an instance call. (pass null for a static (Shared in Visual Basic) method).</param>
670 /// <param name="method">The <see cref="MethodInfo" /> that represents the target method.</param>
671 /// <param name="arguments">An array of one or more of <see cref="Expression" /> that represents the call arguments.</param>
672 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
673 public static MethodCallExpression Call(Expression instance, MethodInfo method, params Expression[] arguments) {
674 return Call(instance, method, (IEnumerable<Expression>)arguments);
678 /// Creates a <see cref="MethodCallExpression" /> that represents a call to a method that takes two arguments.
680 /// <param name="instance">An <see cref="Expression" /> that specifies the instance for an instance call. (pass null for a static (Shared in Visual Basic) method).</param>
681 /// <param name="method">The <see cref="MethodInfo" /> that represents the target method.</param>
682 /// <param name="arg0">The <see cref="Expression" /> that represents the first argument.</param>
683 /// <param name="arg1">The <see cref="Expression" /> that represents the second argument.</param>
684 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
685 public static MethodCallExpression Call(Expression instance, MethodInfo method, Expression arg0, Expression arg1) {
686 ContractUtils.RequiresNotNull(method, "method");
687 ContractUtils.RequiresNotNull(arg0, "arg0");
688 ContractUtils.RequiresNotNull(arg1, "arg1");
690 ParameterInfo[] pis = ValidateMethodAndGetParameters(instance, method);
692 ValidateArgumentCount(method, ExpressionType.Call, 2, pis);
694 arg0 = ValidateOneArgument(method, ExpressionType.Call, arg0, pis[0]);
695 arg1 = ValidateOneArgument(method, ExpressionType.Call, arg1, pis[1]);
697 if (instance != null) {
698 return new InstanceMethodCallExpression2(method, instance, arg0, arg1);
701 return new MethodCallExpression2(method, arg0, arg1);
705 /// Creates a <see cref="MethodCallExpression" /> that represents a call to a method that takes three arguments.
707 /// <param name="instance">An <see cref="Expression" /> that specifies the instance for an instance call. (pass null for a static (Shared in Visual Basic) method).</param>
708 /// <param name="method">The <see cref="MethodInfo" /> that represents the target method.</param>
709 /// <param name="arg0">The <see cref="Expression" /> that represents the first argument.</param>
710 /// <param name="arg1">The <see cref="Expression" /> that represents the second argument.</param>
711 /// <param name="arg2">The <see cref="Expression" /> that represents the third argument.</param>
712 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> properties set to the specified values.</returns>
713 public static MethodCallExpression Call(Expression instance, MethodInfo method, Expression arg0, Expression arg1, Expression arg2) {
714 ContractUtils.RequiresNotNull(method, "method");
715 ContractUtils.RequiresNotNull(arg0, "arg0");
716 ContractUtils.RequiresNotNull(arg1, "arg1");
717 ContractUtils.RequiresNotNull(arg2, "arg2");
719 ParameterInfo[] pis = ValidateMethodAndGetParameters(instance, method);
721 ValidateArgumentCount(method, ExpressionType.Call, 3, pis);
723 arg0 = ValidateOneArgument(method, ExpressionType.Call, arg0, pis[0]);
724 arg1 = ValidateOneArgument(method, ExpressionType.Call, arg1, pis[1]);
725 arg2 = ValidateOneArgument(method, ExpressionType.Call, arg2, pis[2]);
727 if (instance != null) {
728 return new InstanceMethodCallExpression3(method, instance, arg0, arg1, arg2);
730 return new MethodCallExpression3(method, arg0, arg1, arg2);
733 ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents a call to an instance method by calling the appropriate factory method.</summary>
734 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" />, the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> property equal to <paramref name="instance" />, <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> set to the <see cref="T:System.Reflection.MethodInfo" /> that represents the specified instance method, and <see cref="P:System.Linq.Expressions.MethodCallExpression.Arguments" /> set to the specified arguments.</returns>
735 ///<param name="instance">An <see cref="T:System.Linq.Expressions.Expression" /> whose <see cref="P:System.Linq.Expressions.Expression.Type" /> property value will be searched for a specific method.</param>
736 ///<param name="methodName">The name of the method.</param>
737 ///<param name="typeArguments">
738 ///An array of <see cref="T:System.Type" /> objects that specify the type parameters of the generic method.
739 ///This argument should be null when <paramref name="methodName" /> specifies a non-generic method.
741 ///<param name="arguments">An array of <see cref="T:System.Linq.Expressions.Expression" /> objects that represents the arguments to the method.</param>
742 ///<exception cref="T:System.ArgumentNullException">
743 ///<paramref name="instance" /> or <paramref name="methodName" /> is null.</exception>
744 ///<exception cref="T:System.InvalidOperationException">No method whose name is <paramref name="methodName" />, whose type parameters match <paramref name="typeArguments" />, and whose parameter types match <paramref name="arguments" /> is found in <paramref name="instance" />.Type or its base types.-or-More than one method whose name is <paramref name="methodName" />, whose type parameters match <paramref name="typeArguments" />, and whose parameter types match <paramref name="arguments" /> is found in <paramref name="instance" />.Type or its base types.</exception>
745 public static MethodCallExpression Call(Expression instance, string methodName, Type[] typeArguments, params Expression[] arguments) {
746 ContractUtils.RequiresNotNull(instance, "instance");
747 ContractUtils.RequiresNotNull(methodName, "methodName");
748 if (arguments == null) {
749 arguments = new Expression[0];
752 BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
753 return Expression.Call(instance, FindMethod(instance.Type, methodName, typeArguments, arguments, flags), arguments);
756 ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents a call to a static (Shared in Visual Basic) method by calling the appropriate factory method.</summary>
757 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" />, the <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> property set to the <see cref="T:System.Reflection.MethodInfo" /> that represents the specified static (Shared in Visual Basic) method, and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Arguments" /> property set to the specified arguments.</returns>
758 ///<param name="type">The <see cref="T:System.Type" /> that specifies the type that contains the specified static (Shared in Visual Basic) method.</param>
759 ///<param name="methodName">The name of the method.</param>
760 ///<param name="typeArguments">
761 ///An array of <see cref="T:System.Type" /> objects that specify the type parameters of the generic method.
762 ///This argument should be null when <paramref name="methodName" /> specifies a non-generic method.
764 ///<param name="arguments">An array of <see cref="T:System.Linq.Expressions.Expression" /> objects that represent the arguments to the method.</param>
765 ///<exception cref="T:System.ArgumentNullException">
766 ///<paramref name="type" /> or <paramref name="methodName" /> is null.</exception>
767 ///<exception cref="T:System.InvalidOperationException">No method whose name is <paramref name="methodName" />, whose type parameters match <paramref name="typeArguments" />, and whose parameter types match <paramref name="arguments" /> is found in <paramref name="type" /> or its base types.-or-More than one method whose name is <paramref name="methodName" />, whose type parameters match <paramref name="typeArguments" />, and whose parameter types match <paramref name="arguments" /> is found in <paramref name="type" /> or its base types.</exception>
768 public static MethodCallExpression Call(Type type, string methodName, Type[] typeArguments, params Expression[] arguments) {
769 ContractUtils.RequiresNotNull(type, "type");
770 ContractUtils.RequiresNotNull(methodName, "methodName");
772 if (arguments == null) arguments = new Expression[] { };
773 BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
774 return Expression.Call(null, FindMethod(type, methodName, typeArguments, arguments, flags), arguments);
777 ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents a method call.</summary>
778 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" />, <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" />, and <see cref="P:System.Linq.Expressions.MethodCallExpression.Arguments" /> properties set to the specified values.</returns>
779 ///<param name="instance">An <see cref="T:System.Linq.Expressions.Expression" /> to set the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> property equal to (pass null for a static (Shared in Visual Basic) method).</param>
780 ///<param name="method">A <see cref="T:System.Reflection.MethodInfo" /> to set the <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> property equal to.</param>
781 ///<param name="arguments">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> that contains <see cref="T:System.Linq.Expressions.Expression" /> objects to use to populate the <see cref="P:System.Linq.Expressions.MethodCallExpression.Arguments" /> collection.</param>
782 ///<exception cref="T:System.ArgumentNullException">
783 ///<paramref name="method" /> is null.-or-<paramref name="instance" /> is null and <paramref name="method" /> represents an instance method.</exception>
784 ///<exception cref="T:System.ArgumentException">
785 ///<paramref name="instance" />.Type is not assignable to the declaring type of the method represented by <paramref name="method" />.-or-The number of elements in <paramref name="arguments" /> does not equal the number of parameters for the method represented by <paramref name="method" />.-or-One or more of the elements of <paramref name="arguments" /> is not assignable to the corresponding parameter for the method represented by <paramref name="method" />.</exception>
786 public static MethodCallExpression Call(Expression instance, MethodInfo method, IEnumerable<Expression> arguments) {
787 ContractUtils.RequiresNotNull(method, "method");
789 ReadOnlyCollection<Expression> argList = arguments.ToReadOnly();
791 ValidateMethodInfo(method);
792 ValidateStaticOrInstanceMethod(instance, method);
793 ValidateArgumentTypes(method, ExpressionType.Call, ref argList);
795 if (instance == null) {
796 return new MethodCallExpressionN(method, argList);
798 return new InstanceMethodCallExpressionN(method, instance, argList);
802 private static ParameterInfo[] ValidateMethodAndGetParameters(Expression instance, MethodInfo method) {
803 ValidateMethodInfo(method);
804 ValidateStaticOrInstanceMethod(instance, method);
806 return GetParametersForValidation(method, ExpressionType.Call);
809 private static void ValidateStaticOrInstanceMethod(Expression instance, MethodInfo method) {
810 if (method.IsStatic) {
811 if (instance != null) throw new ArgumentException(Strings.OnlyStaticMethodsHaveNullInstance, "instance");
813 if (instance == null) throw new ArgumentException(Strings.OnlyStaticMethodsHaveNullInstance, "method");
814 RequiresCanRead(instance, "instance");
815 ValidateCallInstanceType(instance.Type, method);
819 private static void ValidateCallInstanceType(Type instanceType, MethodInfo method) {
820 if (!TypeUtils.IsValidInstanceType(method, instanceType)) {
821 throw Error.InstanceAndMethodTypeMismatch(method, method.DeclaringType, instanceType);
825 private static void ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ref ReadOnlyCollection<Expression> arguments) {
826 Debug.Assert(nodeKind == ExpressionType.Invoke || nodeKind == ExpressionType.Call || nodeKind == ExpressionType.Dynamic || nodeKind == ExpressionType.New);
828 ParameterInfo[] pis = GetParametersForValidation(method, nodeKind);
830 ValidateArgumentCount(method, nodeKind, arguments.Count, pis);
832 Expression[] newArgs = null;
833 for (int i = 0, n = pis.Length; i < n; i++) {
834 Expression arg = arguments[i];
835 ParameterInfo pi = pis[i];
836 arg = ValidateOneArgument(method, nodeKind, arg, pi);
838 if (newArgs == null && arg != arguments[i]) {
839 newArgs = new Expression[arguments.Count];
840 for (int j = 0; j < i; j++) {
841 newArgs[j] = arguments[j];
844 if (newArgs != null) {
848 if (newArgs != null) {
849 arguments = new TrueReadOnlyCollection<Expression>(newArgs);
853 private static ParameterInfo[] GetParametersForValidation(MethodBase method, ExpressionType nodeKind) {
854 ParameterInfo[] pis = method.GetParametersCached();
856 if (nodeKind == ExpressionType.Dynamic) {
857 pis = pis.RemoveFirst(); // ignore CallSite argument
862 private static void ValidateArgumentCount(MethodBase method, ExpressionType nodeKind, int count, ParameterInfo[] pis) {
863 if (pis.Length != count) {
864 // Throw the right error for the node we were given
866 case ExpressionType.New:
867 throw Error.IncorrectNumberOfConstructorArguments();
868 case ExpressionType.Invoke:
869 throw Error.IncorrectNumberOfLambdaArguments();
870 case ExpressionType.Dynamic:
871 case ExpressionType.Call:
872 throw Error.IncorrectNumberOfMethodCallArguments(method);
874 throw ContractUtils.Unreachable;
879 private static Expression ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi) {
880 RequiresCanRead(arg, "arguments");
881 Type pType = pi.ParameterType;
883 pType = pType.GetElementType();
885 TypeUtils.ValidateType(pType);
886 if (!TypeUtils.AreReferenceAssignable(pType, arg.Type)) {
887 if (!TryQuote(pType, ref arg)) {
888 // Throw the right error for the node we were given
890 case ExpressionType.New:
891 throw Error.ExpressionTypeDoesNotMatchConstructorParameter(arg.Type, pType);
892 case ExpressionType.Invoke:
893 throw Error.ExpressionTypeDoesNotMatchParameter(arg.Type, pType);
894 case ExpressionType.Dynamic:
895 case ExpressionType.Call:
896 throw Error.ExpressionTypeDoesNotMatchMethodParameter(arg.Type, pType, method);
898 throw ContractUtils.Unreachable;
905 // Attempts to auto-quote the expression tree. Returns true if it succeeded, false otherwise.
906 private static bool TryQuote(Type parameterType, ref Expression argument) {
907 // We used to allow quoting of any expression, but the behavior of
908 // quote (produce a new tree closed over parameter values), only
909 // works consistently for lambdas
910 Type quoteable = typeof(LambdaExpression);
911 if (TypeUtils.IsSameOrSubclass(quoteable, parameterType) &&
912 parameterType.IsAssignableFrom(argument.GetType())) {
913 argument = Expression.Quote(argument);
919 private static MethodInfo FindMethod(Type type, string methodName, Type[] typeArgs, Expression[] args, BindingFlags flags) {
920 MemberInfo[] members = type.FindMembers(MemberTypes.Method, flags, Type.FilterNameIgnoreCase, methodName);
921 if (members == null || members.Length == 0)
922 throw Error.MethodDoesNotExistOnType(methodName, type);
926 var methodInfos = members.Map(t => (MethodInfo)t);
927 int count = FindBestMethod(methodInfos, typeArgs, args, out method);
930 if (typeArgs != null && typeArgs.Length > 0) {
931 throw Error.GenericMethodWithArgsDoesNotExistOnType(methodName, type);
933 throw Error.MethodWithArgsDoesNotExistOnType(methodName, type);
937 throw Error.MethodWithMoreThanOneMatch(methodName, type);
941 private static int FindBestMethod(IEnumerable<MethodInfo> methods, Type[] typeArgs, Expression[] args, out MethodInfo method) {
944 foreach (MethodInfo mi in methods) {
945 MethodInfo moo = ApplyTypeArgs(mi, typeArgs);
946 if (moo != null && IsCompatible(moo, args)) {
947 // favor public over non-public methods
948 if (method == null || (!method.IsPublic && moo.IsPublic)) {
952 // only count it as additional method if they both public or both non-public
953 else if (method.IsPublic == moo.IsPublic) {
961 private static bool IsCompatible(MethodBase m, Expression[] args) {
962 ParameterInfo[] parms = m.GetParametersCached();
963 if (parms.Length != args.Length)
965 for (int i = 0; i < args.Length; i++) {
966 Expression arg = args[i];
967 ContractUtils.RequiresNotNull(arg, "argument");
968 Type argType = arg.Type;
969 Type pType = parms[i].ParameterType;
971 pType = pType.GetElementType();
973 if (!TypeUtils.AreReferenceAssignable(pType, argType) &&
974 !(TypeUtils.IsSameOrSubclass(typeof(LambdaExpression), pType) && pType.IsAssignableFrom(arg.GetType()))) {
981 private static MethodInfo ApplyTypeArgs(MethodInfo m, Type[] typeArgs) {
982 if (typeArgs == null || typeArgs.Length == 0) {
983 if (!m.IsGenericMethodDefinition)
986 if (m.IsGenericMethodDefinition && m.GetGenericArguments().Length == typeArgs.Length)
987 return m.MakeGenericMethod(typeArgs);
997 ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents applying an array index operator to a multi-dimensional array.</summary>
998 ///<returns>A <see cref="T:System.Linq.Expressions.BinaryExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.ArrayIndex" /> and the <see cref="P:System.Linq.Expressions.BinaryExpression.Left" /> and <see cref="P:System.Linq.Expressions.BinaryExpression.Right" /> properties set to the specified values.</returns>
999 ///<param name="array">An array of <see cref="T:System.Linq.Expressions.Expression" /> instances - indexes for the array index operation.</param>
1000 ///<param name="indexes">An array that contains <see cref="T:System.Linq.Expressions.Expression" /> objects to use to populate the <see cref="P:System.Linq.Expressions.MethodCallExpression.Arguments" /> collection.</param>
1001 public static MethodCallExpression ArrayIndex(Expression array, params Expression[] indexes) {
1002 return ArrayIndex(array, (IEnumerable<Expression>)indexes);
1005 ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents applying an array index operator to an array of rank more than one.</summary>
1006 ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Arguments" /> properties set to the specified values.</returns>
1007 ///<param name="array">An <see cref="T:System.Linq.Expressions.Expression" /> to set the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> property equal to.</param>
1008 ///<param name="indexes">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> that contains <see cref="T:System.Linq.Expressions.Expression" /> objects to use to populate the <see cref="P:System.Linq.Expressions.MethodCallExpression.Arguments" /> collection.</param>
1009 ///<exception cref="T:System.ArgumentNullException">
1010 ///<paramref name="array" /> or <paramref name="indexes" /> is null.</exception>
1011 ///<exception cref="T:System.ArgumentException">
1012 ///<paramref name="array" />.Type does not represent an array type.-or-The rank of <paramref name="array" />.Type does not match the number of elements in <paramref name="indexes" />.-or-The <see cref="P:System.Linq.Expressions.Expression.Type" /> property of one or more elements of <paramref name="indexes" /> does not represent the <see cref="T:System.Int32" /> type.</exception>
1013 public static MethodCallExpression ArrayIndex(Expression array, IEnumerable<Expression> indexes) {
1014 RequiresCanRead(array, "array");
1015 ContractUtils.RequiresNotNull(indexes, "indexes");
1017 Type arrayType = array.Type;
1018 if (!arrayType.IsArray) {
1019 throw Error.ArgumentMustBeArray();
1022 ReadOnlyCollection<Expression> indexList = indexes.ToReadOnly();
1023 if (arrayType.GetArrayRank() != indexList.Count) {
1024 throw Error.IncorrectNumberOfIndexes();
1027 foreach (Expression e in indexList) {
1028 RequiresCanRead(e, "indexes");
1029 if (e.Type != typeof(int)) {
1030 throw Error.ArgumentMustBeArrayIndexType();
1034 MethodInfo mi = array.Type.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance);
1035 return Call(array, mi, indexList);