private static DynamicExpression MakeDynamic(CallSiteBinder binder, Type returnType, ReadOnlyCollection <Expression> args) { ContractUtils.RequiresNotNull(binder, nameof(binder)); for (int i = 0; i < args.Count; i++) { Expression arg = args[i]; ValidateDynamicArgument(arg, nameof(arg)); } Type delegateType = DelegateHelpers.MakeCallSiteDelegate(args, returnType); // Since we made a delegate with argument types that exactly match, // we can skip delegate and argument validation switch (args.Count) { case 1: return(DynamicExpression.Make(returnType, delegateType, binder, args[0])); case 2: return(DynamicExpression.Make(returnType, delegateType, binder, args[0], args[1])); case 3: return(DynamicExpression.Make(returnType, delegateType, binder, args[0], args[1], args[2])); case 4: return(DynamicExpression.Make(returnType, delegateType, binder, args[0], args[1], args[2], args[3])); default: return(DynamicExpression.Make(returnType, delegateType, binder, args)); } }
/// <summary> /// Creates a <see cref="DynamicExpression" /> that represents a dynamic operation bound by the provided <see cref="CallSiteBinder" />. /// </summary> /// <param name="binder">The runtime binder for the dynamic operation.</param> /// <param name="returnType">The result type of the dynamic expression.</param> /// <param name="arg0">The first argument to the dynamic operation.</param> /// <param name="arg1">The second argument to the dynamic operation.</param> /// <param name="arg2">The third argument to the dynamic operation.</param> /// <param name="arg3">The fourth argument to the dynamic operation.</param> /// <returns> /// A <see cref="DynamicExpression" /> that has <see cref="NodeType" /> equal to /// <see cref="ExpressionType.Dynamic">Dynamic</see> and has the /// <see cref="DynamicExpression.Binder">Binder</see> and /// <see cref="DynamicExpression.Arguments">Arguments</see> set to the specified values. /// </returns> /// <remarks> /// The <see cref="DynamicExpression.DelegateType">DelegateType</see> property of the /// result will be inferred from the types of the arguments and the specified return type. /// </remarks> public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1, Expression arg2, Expression arg3) { ContractUtils.RequiresNotNull(binder, nameof(binder)); ValidateDynamicArgument(arg0, nameof(arg0)); ValidateDynamicArgument(arg1, nameof(arg1)); ValidateDynamicArgument(arg2, nameof(arg2)); ValidateDynamicArgument(arg3, nameof(arg3)); DelegateHelpers.TypeInfo info = DelegateHelpers.GetNextTypeInfo( returnType, DelegateHelpers.GetNextTypeInfo( arg3.Type, DelegateHelpers.GetNextTypeInfo( arg2.Type, DelegateHelpers.GetNextTypeInfo( arg1.Type, DelegateHelpers.GetNextTypeInfo( arg0.Type, DelegateHelpers.NextTypeInfo(typeof(CallSite)) ) ) ) ) ); Type delegateType = info.DelegateType ?? info.MakeDelegateType(returnType, arg0, arg1, arg2, arg3); return(DynamicExpression.Make(returnType, delegateType, binder, arg0, arg1, arg2, arg3)); }