Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Ast / DynamicExpression.cs / 1305376 / DynamicExpression.cs
/* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Dynamic.Utils; using System.Linq.Expressions.Compiler; using System.Reflection; using System.Runtime.CompilerServices; #if SILVERLIGHT using System.Core; #endif namespace System.Linq.Expressions { ////// Represents a dynamic operation. /// #if !SILVERLIGHT [DebuggerTypeProxy(typeof(Expression.DynamicExpressionProxy))] #endif public class DynamicExpression : Expression, IArgumentProvider { private readonly CallSiteBinder _binder; private readonly Type _delegateType; internal DynamicExpression(Type delegateType, CallSiteBinder binder) { Debug.Assert(delegateType.GetMethod("Invoke").GetReturnType() == typeof(object) || GetType() != typeof(DynamicExpression)); _delegateType = delegateType; _binder = binder; } internal static DynamicExpression Make(Type returnType, Type delegateType, CallSiteBinder binder, ReadOnlyCollectionarguments) { if (returnType == typeof(object)) { return new DynamicExpressionN(delegateType, binder, arguments); } else { return new TypedDynamicExpressionN(returnType, delegateType, binder, arguments); } } internal static DynamicExpression Make(Type returnType, Type delegateType, CallSiteBinder binder, Expression arg0) { if (returnType == typeof(object)) { return new DynamicExpression1(delegateType, binder, arg0); } else { return new TypedDynamicExpression1(returnType, delegateType, binder, arg0); } } internal static DynamicExpression Make(Type returnType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1) { if (returnType == typeof(object)) { return new DynamicExpression2(delegateType, binder, arg0, arg1); } else { return new TypedDynamicExpression2(returnType, delegateType, binder, arg0, arg1); } } internal static DynamicExpression Make(Type returnType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2) { if (returnType == typeof(object)) { return new DynamicExpression3(delegateType, binder, arg0, arg1, arg2); } else { return new TypedDynamicExpression3(returnType, delegateType, binder, arg0, arg1, arg2); } } internal static DynamicExpression Make(Type returnType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2, Expression arg3) { if (returnType == typeof(object)) { return new DynamicExpression4(delegateType, binder, arg0, arg1, arg2, arg3); } else { return new TypedDynamicExpression4(returnType, delegateType, binder, arg0, arg1, arg2, arg3); } } /// /// Gets the static type of the expression that this ///represents. /// The public override Type Type { get { return typeof(object); } } ///that represents the static type of the expression. /// Returns the node type of this Expression. Extension nodes should return /// ExpressionType.Extension when overriding this method. /// ///The public sealed override ExpressionType NodeType { get { return ExpressionType.Dynamic; } } ///of the expression. /// Gets the public CallSiteBinder Binder { get { return _binder; } } ///, which determines the runtime behavior of the /// dynamic site. /// /// Gets the type of the delegate used by the public Type DelegateType { get { return _delegateType; } } ///. /// /// Gets the arguments to the dynamic operation. /// public ReadOnlyCollectionArguments { get { return GetOrMakeArguments(); } } internal virtual ReadOnlyCollection GetOrMakeArguments() { throw ContractUtils.Unreachable; } /// /// Dispatches to the specific visit method for this node type. /// protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitDynamic(this); } ////// Makes a copy of this node replacing the args with the provided values. The /// number of the args needs to match the number of the current block. /// /// This helper is provided to allow re-writing of nodes to not depend on the specific optimized /// subclass of DynamicExpression which is being used. /// internal virtual DynamicExpression Rewrite(Expression[] args) { throw ContractUtils.Unreachable; } ////// 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. /// /// Theproperty of the result. /// This expression if no children changed, or an expression with the updated children. public DynamicExpression Update(IEnumerablearguments) { if (arguments == Arguments) { return this; } return Expression.MakeDynamic(DelegateType, Binder, arguments); } #region IArgumentProvider Members Expression IArgumentProvider.GetArgument(int index) { throw ContractUtils.Unreachable; } int IArgumentProvider.ArgumentCount { get { throw ContractUtils.Unreachable; } } #endregion } #region Specialized Subclasses internal class DynamicExpressionN : DynamicExpression, IArgumentProvider { private IList _arguments; // storage for the original IList or readonly collection. See IArgumentProvider for more info. internal DynamicExpressionN(Type delegateType, CallSiteBinder binder, IList arguments) : base(delegateType, binder) { _arguments = arguments; } Expression IArgumentProvider.GetArgument(int index) { return _arguments[index]; } int IArgumentProvider.ArgumentCount { get { return _arguments.Count; } } internal override ReadOnlyCollection GetOrMakeArguments() { return ReturnReadOnly(ref _arguments); } internal override DynamicExpression Rewrite(Expression[] args) { Debug.Assert(args.Length == ((IArgumentProvider)this).ArgumentCount); return Expression.MakeDynamic(DelegateType, Binder, args); } } internal class TypedDynamicExpressionN : DynamicExpressionN { private readonly Type _returnType; internal TypedDynamicExpressionN(Type returnType, Type delegateType, CallSiteBinder binder, IList arguments) : base(delegateType, binder, arguments) { Debug.Assert(delegateType.GetMethod("Invoke").GetReturnType() == returnType); _returnType = returnType; } public sealed override Type Type { get { return _returnType; } } } internal class DynamicExpression1 : DynamicExpression, IArgumentProvider { private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider for more info. internal DynamicExpression1(Type delegateType, CallSiteBinder binder, Expression arg0) : base(delegateType, binder) { _arg0 = arg0; } Expression IArgumentProvider.GetArgument(int index) { switch (index) { case 0: return ReturnObject (_arg0); default: throw new InvalidOperationException(); } } int IArgumentProvider.ArgumentCount { get { return 1; } } internal override ReadOnlyCollection GetOrMakeArguments() { return ReturnReadOnly(this, ref _arg0); } internal override DynamicExpression Rewrite(Expression[] args) { Debug.Assert(args.Length == 1); return Expression.MakeDynamic(DelegateType, Binder, args[0]); } } internal sealed class TypedDynamicExpression1 : DynamicExpression1 { private readonly Type _retType; internal TypedDynamicExpression1(Type retType, Type delegateType, CallSiteBinder binder, Expression arg0) : base(delegateType, binder, arg0) { _retType = retType; } public sealed override Type Type { get { return _retType; } } } internal class DynamicExpression2 : DynamicExpression, IArgumentProvider { private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider for more info. private readonly Expression _arg1; // storage for the 2nd argument internal DynamicExpression2(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1) : base(delegateType, binder) { _arg0 = arg0; _arg1 = arg1; } Expression IArgumentProvider.GetArgument(int index) { switch (index) { case 0: return ReturnObject (_arg0); case 1: return _arg1; default: throw new InvalidOperationException(); } } int IArgumentProvider.ArgumentCount { get { return 2; } } internal override ReadOnlyCollection GetOrMakeArguments() { return ReturnReadOnly(this, ref _arg0); } internal override DynamicExpression Rewrite(Expression[] args) { Debug.Assert(args.Length == 2); return Expression.MakeDynamic(DelegateType, Binder, args[0], args[1]); } } internal sealed class TypedDynamicExpression2 : DynamicExpression2 { private readonly Type _retType; internal TypedDynamicExpression2(Type retType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1) : base(delegateType, binder, arg0, arg1) { _retType = retType; } public sealed override Type Type { get { return _retType; } } } internal class DynamicExpression3 : DynamicExpression, IArgumentProvider { private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider for more info. private readonly Expression _arg1, _arg2; // storage for the 2nd & 3rd arguments internal DynamicExpression3(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2) : base(delegateType, binder) { _arg0 = arg0; _arg1 = arg1; _arg2 = arg2; } Expression IArgumentProvider.GetArgument(int index) { switch (index) { case 0: return ReturnObject (_arg0); case 1: return _arg1; case 2: return _arg2; default: throw new InvalidOperationException(); } } int IArgumentProvider.ArgumentCount { get { return 3; } } internal override ReadOnlyCollection GetOrMakeArguments() { return ReturnReadOnly(this, ref _arg0); } internal override DynamicExpression Rewrite(Expression[] args) { Debug.Assert(args.Length == 3); return Expression.MakeDynamic(DelegateType, Binder, args[0], args[1], args[2]); } } internal sealed class TypedDynamicExpression3 : DynamicExpression3 { private readonly Type _retType; internal TypedDynamicExpression3(Type retType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2) : base(delegateType, binder, arg0, arg1, arg2) { _retType = retType; } public sealed override Type Type { get { return _retType; } } } internal class DynamicExpression4 : DynamicExpression, IArgumentProvider { private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider for more info. private readonly Expression _arg1, _arg2, _arg3; // storage for the 2nd - 4th arguments internal DynamicExpression4(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2, Expression arg3) : base(delegateType, binder) { _arg0 = arg0; _arg1 = arg1; _arg2 = arg2; _arg3 = arg3; } Expression IArgumentProvider.GetArgument(int index) { switch (index) { case 0: return ReturnObject (_arg0); case 1: return _arg1; case 2: return _arg2; case 3: return _arg3; default: throw new InvalidOperationException(); } } int IArgumentProvider.ArgumentCount { get { return 4; } } internal override ReadOnlyCollection GetOrMakeArguments() { return ReturnReadOnly(this, ref _arg0); } internal override DynamicExpression Rewrite(Expression[] args) { Debug.Assert(args.Length == 4); return Expression.MakeDynamic(DelegateType, Binder, args[0], args[1], args[2], args[3]); } } internal sealed class TypedDynamicExpression4 : DynamicExpression4 { private readonly Type _retType; internal TypedDynamicExpression4(Type retType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2, Expression arg3) : base(delegateType, binder, arg0, arg1, arg2, arg3) { _retType = retType; } public sealed override Type Type { get { return _retType; } } } #endregion public partial class Expression { /// /// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided . /// . /// The runtime binder for the dynamic operation. /// The arguments to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, params Expression[] arguments) { return MakeDynamic(delegateType, binder, (IEnumerablethat has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ///)arguments); } /// /// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided . /// . /// The runtime binder for the dynamic operation. /// The arguments to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, IEnumerablethat has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ///arguments) { ContractUtils.RequiresNotNull(delegateType, "delegateType"); ContractUtils.RequiresNotNull(binder, "binder"); if (!delegateType.IsSubclassOf(typeof(Delegate))) throw Error.TypeMustBeDerivedFromSystemDelegate(); var method = GetValidMethodForDynamic(delegateType); var args = arguments.ToReadOnly(); ValidateArgumentTypes(method, ExpressionType.Dynamic, ref args); return DynamicExpression.Make(method.GetReturnType(), delegateType, binder, args); } /// /// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided and one argument. /// . /// The runtime binder for the dynamic operation. /// The argument to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0) { ContractUtils.RequiresNotNull(delegateType, "delegatType"); ContractUtils.RequiresNotNull(binder, "binder"); if (!delegateType.IsSubclassOf(typeof(Delegate))) throw Error.TypeMustBeDerivedFromSystemDelegate(); var method = GetValidMethodForDynamic(delegateType); var parameters = method.GetParametersCached(); ValidateArgumentCount(method, ExpressionType.Dynamic, 2, parameters); ValidateDynamicArgument(arg0); ValidateOneArgument(method, ExpressionType.Dynamic, arg0, parameters[1]); return DynamicExpression.Make(method.GetReturnType(), delegateType, binder, arg0); } ///that has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ////// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided and two arguments. /// . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1) { ContractUtils.RequiresNotNull(delegateType, "delegatType"); ContractUtils.RequiresNotNull(binder, "binder"); if (!delegateType.IsSubclassOf(typeof(Delegate))) throw Error.TypeMustBeDerivedFromSystemDelegate(); var method = GetValidMethodForDynamic(delegateType); var parameters = method.GetParametersCached(); ValidateArgumentCount(method, ExpressionType.Dynamic, 3, parameters); ValidateDynamicArgument(arg0); ValidateOneArgument(method, ExpressionType.Dynamic, arg0, parameters[1]); ValidateDynamicArgument(arg1); ValidateOneArgument(method, ExpressionType.Dynamic, arg1, parameters[2]); return DynamicExpression.Make(method.GetReturnType(), delegateType, binder, arg0, arg1); } ///that has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ////// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided and three arguments. /// . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2) { ContractUtils.RequiresNotNull(delegateType, "delegatType"); ContractUtils.RequiresNotNull(binder, "binder"); if (!delegateType.IsSubclassOf(typeof(Delegate))) throw Error.TypeMustBeDerivedFromSystemDelegate(); var method = GetValidMethodForDynamic(delegateType); var parameters = method.GetParametersCached(); ValidateArgumentCount(method, ExpressionType.Dynamic, 4, parameters); ValidateDynamicArgument(arg0); ValidateOneArgument(method, ExpressionType.Dynamic, arg0, parameters[1]); ValidateDynamicArgument(arg1); ValidateOneArgument(method, ExpressionType.Dynamic, arg1, parameters[2]); ValidateDynamicArgument(arg2); ValidateOneArgument(method, ExpressionType.Dynamic, arg2, parameters[3]); return DynamicExpression.Make(method.GetReturnType(), delegateType, binder, arg0, arg1, arg2); } ///that has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ////// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided and four arguments. /// . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. /// The fourth argument to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2, Expression arg3) { ContractUtils.RequiresNotNull(delegateType, "delegatType"); ContractUtils.RequiresNotNull(binder, "binder"); if (!delegateType.IsSubclassOf(typeof(Delegate))) throw Error.TypeMustBeDerivedFromSystemDelegate(); var method = GetValidMethodForDynamic(delegateType); var parameters = method.GetParametersCached(); ValidateArgumentCount(method, ExpressionType.Dynamic, 5, parameters); ValidateDynamicArgument(arg0); ValidateOneArgument(method, ExpressionType.Dynamic, arg0, parameters[1]); ValidateDynamicArgument(arg1); ValidateOneArgument(method, ExpressionType.Dynamic, arg1, parameters[2]); ValidateDynamicArgument(arg2); ValidateOneArgument(method, ExpressionType.Dynamic, arg2, parameters[3]); ValidateDynamicArgument(arg3); ValidateOneArgument(method, ExpressionType.Dynamic, arg3, parameters[4]); return DynamicExpression.Make(method.GetReturnType(), delegateType, binder, arg0, arg1, arg2, arg3); } private static MethodInfo GetValidMethodForDynamic(Type delegateType) { var method = delegateType.GetMethod("Invoke"); var pi = method.GetParametersCached(); if (pi.Length == 0 || pi[0].ParameterType != typeof(CallSite)) throw Error.FirstArgumentMustBeCallSite(); return method; } ///that has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ////// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The arguments to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, params Expression[] arguments) { return Dynamic(binder, returnType, (IEnumerableDelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ///)arguments); } /// /// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0) { ContractUtils.RequiresNotNull(binder, "binder"); ValidateDynamicArgument(arg0); DelegateHelpers.TypeInfo info = DelegateHelpers.GetNextTypeInfo( returnType, DelegateHelpers.GetNextTypeInfo( arg0.Type, DelegateHelpers.NextTypeInfo(typeof(CallSite)) ) ); Type delegateType = info.DelegateType; if (delegateType == null) { delegateType = info.MakeDelegateType(returnType, arg0); } return DynamicExpression.Make(returnType, delegateType, binder, arg0); } ///DelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ////// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1) { ContractUtils.RequiresNotNull(binder, "binder"); ValidateDynamicArgument(arg0); ValidateDynamicArgument(arg1); DelegateHelpers.TypeInfo info = DelegateHelpers.GetNextTypeInfo( returnType, DelegateHelpers.GetNextTypeInfo( arg1.Type, DelegateHelpers.GetNextTypeInfo( arg0.Type, DelegateHelpers.NextTypeInfo(typeof(CallSite)) ) ) ); Type delegateType = info.DelegateType; if (delegateType == null) { delegateType = info.MakeDelegateType(returnType, arg0, arg1); } return DynamicExpression.Make(returnType, delegateType, binder, arg0, arg1); } ///DelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ////// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1, Expression arg2) { ContractUtils.RequiresNotNull(binder, "binder"); ValidateDynamicArgument(arg0); ValidateDynamicArgument(arg1); ValidateDynamicArgument(arg2); DelegateHelpers.TypeInfo info = DelegateHelpers.GetNextTypeInfo( returnType, DelegateHelpers.GetNextTypeInfo( arg2.Type, DelegateHelpers.GetNextTypeInfo( arg1.Type, DelegateHelpers.GetNextTypeInfo( arg0.Type, DelegateHelpers.NextTypeInfo(typeof(CallSite)) ) ) ) ); Type delegateType = info.DelegateType; if (delegateType == null) { delegateType = info.MakeDelegateType(returnType, arg0, arg1, arg2); } return DynamicExpression.Make(returnType, delegateType, binder, arg0, arg1, arg2); } ///DelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ////// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. /// The fourth argument to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1, Expression arg2, Expression arg3) { ContractUtils.RequiresNotNull(binder, "binder"); ValidateDynamicArgument(arg0); ValidateDynamicArgument(arg1); ValidateDynamicArgument(arg2); ValidateDynamicArgument(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; if (delegateType == null) { delegateType = info.MakeDelegateType(returnType, arg0, arg1, arg2, arg3); } return DynamicExpression.Make(returnType, delegateType, binder, arg0, arg1, arg2, arg3); } ///DelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ////// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The arguments to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, IEnumerableDelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ///arguments) { ContractUtils.RequiresNotNull(arguments, "arguments"); ContractUtils.RequiresNotNull(returnType, "returnType"); var args = arguments.ToReadOnly(); ContractUtils.RequiresNotEmpty(args, "args"); return MakeDynamic(binder, returnType, args); } private static DynamicExpression MakeDynamic(CallSiteBinder binder, Type returnType, ReadOnlyCollection args) { ContractUtils.RequiresNotNull(binder, "binder"); for (int i = 0; i < args.Count; i++) { Expression arg = args[i]; ValidateDynamicArgument(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); } } private static void ValidateDynamicArgument(Expression arg) { RequiresCanRead(arg, "arguments"); var type = arg.Type; ContractUtils.RequiresNotNull(type, "type"); TypeUtils.ValidateType(type); if (type == typeof(void)) throw Error.ArgumentTypeCannotBeVoid(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. /* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Dynamic.Utils; using System.Linq.Expressions.Compiler; using System.Reflection; using System.Runtime.CompilerServices; #if SILVERLIGHT using System.Core; #endif namespace System.Linq.Expressions { /// /// Represents a dynamic operation. /// #if !SILVERLIGHT [DebuggerTypeProxy(typeof(Expression.DynamicExpressionProxy))] #endif public class DynamicExpression : Expression, IArgumentProvider { private readonly CallSiteBinder _binder; private readonly Type _delegateType; internal DynamicExpression(Type delegateType, CallSiteBinder binder) { Debug.Assert(delegateType.GetMethod("Invoke").GetReturnType() == typeof(object) || GetType() != typeof(DynamicExpression)); _delegateType = delegateType; _binder = binder; } internal static DynamicExpression Make(Type returnType, Type delegateType, CallSiteBinder binder, ReadOnlyCollectionarguments) { if (returnType == typeof(object)) { return new DynamicExpressionN(delegateType, binder, arguments); } else { return new TypedDynamicExpressionN(returnType, delegateType, binder, arguments); } } internal static DynamicExpression Make(Type returnType, Type delegateType, CallSiteBinder binder, Expression arg0) { if (returnType == typeof(object)) { return new DynamicExpression1(delegateType, binder, arg0); } else { return new TypedDynamicExpression1(returnType, delegateType, binder, arg0); } } internal static DynamicExpression Make(Type returnType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1) { if (returnType == typeof(object)) { return new DynamicExpression2(delegateType, binder, arg0, arg1); } else { return new TypedDynamicExpression2(returnType, delegateType, binder, arg0, arg1); } } internal static DynamicExpression Make(Type returnType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2) { if (returnType == typeof(object)) { return new DynamicExpression3(delegateType, binder, arg0, arg1, arg2); } else { return new TypedDynamicExpression3(returnType, delegateType, binder, arg0, arg1, arg2); } } internal static DynamicExpression Make(Type returnType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2, Expression arg3) { if (returnType == typeof(object)) { return new DynamicExpression4(delegateType, binder, arg0, arg1, arg2, arg3); } else { return new TypedDynamicExpression4(returnType, delegateType, binder, arg0, arg1, arg2, arg3); } } /// /// Gets the static type of the expression that this ///represents. /// The public override Type Type { get { return typeof(object); } } ///that represents the static type of the expression. /// Returns the node type of this Expression. Extension nodes should return /// ExpressionType.Extension when overriding this method. /// ///The public sealed override ExpressionType NodeType { get { return ExpressionType.Dynamic; } } ///of the expression. /// Gets the public CallSiteBinder Binder { get { return _binder; } } ///, which determines the runtime behavior of the /// dynamic site. /// /// Gets the type of the delegate used by the public Type DelegateType { get { return _delegateType; } } ///. /// /// Gets the arguments to the dynamic operation. /// public ReadOnlyCollectionArguments { get { return GetOrMakeArguments(); } } internal virtual ReadOnlyCollection GetOrMakeArguments() { throw ContractUtils.Unreachable; } /// /// Dispatches to the specific visit method for this node type. /// protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitDynamic(this); } ////// Makes a copy of this node replacing the args with the provided values. The /// number of the args needs to match the number of the current block. /// /// This helper is provided to allow re-writing of nodes to not depend on the specific optimized /// subclass of DynamicExpression which is being used. /// internal virtual DynamicExpression Rewrite(Expression[] args) { throw ContractUtils.Unreachable; } ////// 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. /// /// Theproperty of the result. /// This expression if no children changed, or an expression with the updated children. public DynamicExpression Update(IEnumerablearguments) { if (arguments == Arguments) { return this; } return Expression.MakeDynamic(DelegateType, Binder, arguments); } #region IArgumentProvider Members Expression IArgumentProvider.GetArgument(int index) { throw ContractUtils.Unreachable; } int IArgumentProvider.ArgumentCount { get { throw ContractUtils.Unreachable; } } #endregion } #region Specialized Subclasses internal class DynamicExpressionN : DynamicExpression, IArgumentProvider { private IList _arguments; // storage for the original IList or readonly collection. See IArgumentProvider for more info. internal DynamicExpressionN(Type delegateType, CallSiteBinder binder, IList arguments) : base(delegateType, binder) { _arguments = arguments; } Expression IArgumentProvider.GetArgument(int index) { return _arguments[index]; } int IArgumentProvider.ArgumentCount { get { return _arguments.Count; } } internal override ReadOnlyCollection GetOrMakeArguments() { return ReturnReadOnly(ref _arguments); } internal override DynamicExpression Rewrite(Expression[] args) { Debug.Assert(args.Length == ((IArgumentProvider)this).ArgumentCount); return Expression.MakeDynamic(DelegateType, Binder, args); } } internal class TypedDynamicExpressionN : DynamicExpressionN { private readonly Type _returnType; internal TypedDynamicExpressionN(Type returnType, Type delegateType, CallSiteBinder binder, IList arguments) : base(delegateType, binder, arguments) { Debug.Assert(delegateType.GetMethod("Invoke").GetReturnType() == returnType); _returnType = returnType; } public sealed override Type Type { get { return _returnType; } } } internal class DynamicExpression1 : DynamicExpression, IArgumentProvider { private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider for more info. internal DynamicExpression1(Type delegateType, CallSiteBinder binder, Expression arg0) : base(delegateType, binder) { _arg0 = arg0; } Expression IArgumentProvider.GetArgument(int index) { switch (index) { case 0: return ReturnObject (_arg0); default: throw new InvalidOperationException(); } } int IArgumentProvider.ArgumentCount { get { return 1; } } internal override ReadOnlyCollection GetOrMakeArguments() { return ReturnReadOnly(this, ref _arg0); } internal override DynamicExpression Rewrite(Expression[] args) { Debug.Assert(args.Length == 1); return Expression.MakeDynamic(DelegateType, Binder, args[0]); } } internal sealed class TypedDynamicExpression1 : DynamicExpression1 { private readonly Type _retType; internal TypedDynamicExpression1(Type retType, Type delegateType, CallSiteBinder binder, Expression arg0) : base(delegateType, binder, arg0) { _retType = retType; } public sealed override Type Type { get { return _retType; } } } internal class DynamicExpression2 : DynamicExpression, IArgumentProvider { private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider for more info. private readonly Expression _arg1; // storage for the 2nd argument internal DynamicExpression2(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1) : base(delegateType, binder) { _arg0 = arg0; _arg1 = arg1; } Expression IArgumentProvider.GetArgument(int index) { switch (index) { case 0: return ReturnObject (_arg0); case 1: return _arg1; default: throw new InvalidOperationException(); } } int IArgumentProvider.ArgumentCount { get { return 2; } } internal override ReadOnlyCollection GetOrMakeArguments() { return ReturnReadOnly(this, ref _arg0); } internal override DynamicExpression Rewrite(Expression[] args) { Debug.Assert(args.Length == 2); return Expression.MakeDynamic(DelegateType, Binder, args[0], args[1]); } } internal sealed class TypedDynamicExpression2 : DynamicExpression2 { private readonly Type _retType; internal TypedDynamicExpression2(Type retType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1) : base(delegateType, binder, arg0, arg1) { _retType = retType; } public sealed override Type Type { get { return _retType; } } } internal class DynamicExpression3 : DynamicExpression, IArgumentProvider { private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider for more info. private readonly Expression _arg1, _arg2; // storage for the 2nd & 3rd arguments internal DynamicExpression3(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2) : base(delegateType, binder) { _arg0 = arg0; _arg1 = arg1; _arg2 = arg2; } Expression IArgumentProvider.GetArgument(int index) { switch (index) { case 0: return ReturnObject (_arg0); case 1: return _arg1; case 2: return _arg2; default: throw new InvalidOperationException(); } } int IArgumentProvider.ArgumentCount { get { return 3; } } internal override ReadOnlyCollection GetOrMakeArguments() { return ReturnReadOnly(this, ref _arg0); } internal override DynamicExpression Rewrite(Expression[] args) { Debug.Assert(args.Length == 3); return Expression.MakeDynamic(DelegateType, Binder, args[0], args[1], args[2]); } } internal sealed class TypedDynamicExpression3 : DynamicExpression3 { private readonly Type _retType; internal TypedDynamicExpression3(Type retType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2) : base(delegateType, binder, arg0, arg1, arg2) { _retType = retType; } public sealed override Type Type { get { return _retType; } } } internal class DynamicExpression4 : DynamicExpression, IArgumentProvider { private object _arg0; // storage for the 1st argument or a readonly collection. See IArgumentProvider for more info. private readonly Expression _arg1, _arg2, _arg3; // storage for the 2nd - 4th arguments internal DynamicExpression4(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2, Expression arg3) : base(delegateType, binder) { _arg0 = arg0; _arg1 = arg1; _arg2 = arg2; _arg3 = arg3; } Expression IArgumentProvider.GetArgument(int index) { switch (index) { case 0: return ReturnObject (_arg0); case 1: return _arg1; case 2: return _arg2; case 3: return _arg3; default: throw new InvalidOperationException(); } } int IArgumentProvider.ArgumentCount { get { return 4; } } internal override ReadOnlyCollection GetOrMakeArguments() { return ReturnReadOnly(this, ref _arg0); } internal override DynamicExpression Rewrite(Expression[] args) { Debug.Assert(args.Length == 4); return Expression.MakeDynamic(DelegateType, Binder, args[0], args[1], args[2], args[3]); } } internal sealed class TypedDynamicExpression4 : DynamicExpression4 { private readonly Type _retType; internal TypedDynamicExpression4(Type retType, Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2, Expression arg3) : base(delegateType, binder, arg0, arg1, arg2, arg3) { _retType = retType; } public sealed override Type Type { get { return _retType; } } } #endregion public partial class Expression { /// /// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided . /// . /// The runtime binder for the dynamic operation. /// The arguments to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, params Expression[] arguments) { return MakeDynamic(delegateType, binder, (IEnumerablethat has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ///)arguments); } /// /// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided . /// . /// The runtime binder for the dynamic operation. /// The arguments to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, IEnumerablethat has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ///arguments) { ContractUtils.RequiresNotNull(delegateType, "delegateType"); ContractUtils.RequiresNotNull(binder, "binder"); if (!delegateType.IsSubclassOf(typeof(Delegate))) throw Error.TypeMustBeDerivedFromSystemDelegate(); var method = GetValidMethodForDynamic(delegateType); var args = arguments.ToReadOnly(); ValidateArgumentTypes(method, ExpressionType.Dynamic, ref args); return DynamicExpression.Make(method.GetReturnType(), delegateType, binder, args); } /// /// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided and one argument. /// . /// The runtime binder for the dynamic operation. /// The argument to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0) { ContractUtils.RequiresNotNull(delegateType, "delegatType"); ContractUtils.RequiresNotNull(binder, "binder"); if (!delegateType.IsSubclassOf(typeof(Delegate))) throw Error.TypeMustBeDerivedFromSystemDelegate(); var method = GetValidMethodForDynamic(delegateType); var parameters = method.GetParametersCached(); ValidateArgumentCount(method, ExpressionType.Dynamic, 2, parameters); ValidateDynamicArgument(arg0); ValidateOneArgument(method, ExpressionType.Dynamic, arg0, parameters[1]); return DynamicExpression.Make(method.GetReturnType(), delegateType, binder, arg0); } ///that has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ////// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided and two arguments. /// . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1) { ContractUtils.RequiresNotNull(delegateType, "delegatType"); ContractUtils.RequiresNotNull(binder, "binder"); if (!delegateType.IsSubclassOf(typeof(Delegate))) throw Error.TypeMustBeDerivedFromSystemDelegate(); var method = GetValidMethodForDynamic(delegateType); var parameters = method.GetParametersCached(); ValidateArgumentCount(method, ExpressionType.Dynamic, 3, parameters); ValidateDynamicArgument(arg0); ValidateOneArgument(method, ExpressionType.Dynamic, arg0, parameters[1]); ValidateDynamicArgument(arg1); ValidateOneArgument(method, ExpressionType.Dynamic, arg1, parameters[2]); return DynamicExpression.Make(method.GetReturnType(), delegateType, binder, arg0, arg1); } ///that has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ////// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided and three arguments. /// . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2) { ContractUtils.RequiresNotNull(delegateType, "delegatType"); ContractUtils.RequiresNotNull(binder, "binder"); if (!delegateType.IsSubclassOf(typeof(Delegate))) throw Error.TypeMustBeDerivedFromSystemDelegate(); var method = GetValidMethodForDynamic(delegateType); var parameters = method.GetParametersCached(); ValidateArgumentCount(method, ExpressionType.Dynamic, 4, parameters); ValidateDynamicArgument(arg0); ValidateOneArgument(method, ExpressionType.Dynamic, arg0, parameters[1]); ValidateDynamicArgument(arg1); ValidateOneArgument(method, ExpressionType.Dynamic, arg1, parameters[2]); ValidateDynamicArgument(arg2); ValidateOneArgument(method, ExpressionType.Dynamic, arg2, parameters[3]); return DynamicExpression.Make(method.GetReturnType(), delegateType, binder, arg0, arg1, arg2); } ///that has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ////// Creates a /// The type of the delegate used by thethat represents a dynamic operation bound by the provided and four arguments. /// . /// The runtime binder for the dynamic operation. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. /// The fourth argument to the dynamic operation. /// /// A public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, Expression arg0, Expression arg1, Expression arg2, Expression arg3) { ContractUtils.RequiresNotNull(delegateType, "delegatType"); ContractUtils.RequiresNotNull(binder, "binder"); if (!delegateType.IsSubclassOf(typeof(Delegate))) throw Error.TypeMustBeDerivedFromSystemDelegate(); var method = GetValidMethodForDynamic(delegateType); var parameters = method.GetParametersCached(); ValidateArgumentCount(method, ExpressionType.Dynamic, 5, parameters); ValidateDynamicArgument(arg0); ValidateOneArgument(method, ExpressionType.Dynamic, arg0, parameters[1]); ValidateDynamicArgument(arg1); ValidateOneArgument(method, ExpressionType.Dynamic, arg1, parameters[2]); ValidateDynamicArgument(arg2); ValidateOneArgument(method, ExpressionType.Dynamic, arg2, parameters[3]); ValidateDynamicArgument(arg3); ValidateOneArgument(method, ExpressionType.Dynamic, arg3, parameters[4]); return DynamicExpression.Make(method.GetReturnType(), delegateType, binder, arg0, arg1, arg2, arg3); } private static MethodInfo GetValidMethodForDynamic(Type delegateType) { var method = delegateType.GetMethod("Invoke"); var pi = method.GetParametersCached(); if (pi.Length == 0 || pi[0].ParameterType != typeof(CallSite)) throw Error.FirstArgumentMustBeCallSite(); return method; } ///that has equal to /// Dynamic and has the ///DelegateType , ///Binder , and ///Arguments set to the specified values. ////// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The arguments to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, params Expression[] arguments) { return Dynamic(binder, returnType, (IEnumerableDelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ///)arguments); } /// /// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0) { ContractUtils.RequiresNotNull(binder, "binder"); ValidateDynamicArgument(arg0); DelegateHelpers.TypeInfo info = DelegateHelpers.GetNextTypeInfo( returnType, DelegateHelpers.GetNextTypeInfo( arg0.Type, DelegateHelpers.NextTypeInfo(typeof(CallSite)) ) ); Type delegateType = info.DelegateType; if (delegateType == null) { delegateType = info.MakeDelegateType(returnType, arg0); } return DynamicExpression.Make(returnType, delegateType, binder, arg0); } ///DelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ////// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1) { ContractUtils.RequiresNotNull(binder, "binder"); ValidateDynamicArgument(arg0); ValidateDynamicArgument(arg1); DelegateHelpers.TypeInfo info = DelegateHelpers.GetNextTypeInfo( returnType, DelegateHelpers.GetNextTypeInfo( arg1.Type, DelegateHelpers.GetNextTypeInfo( arg0.Type, DelegateHelpers.NextTypeInfo(typeof(CallSite)) ) ) ); Type delegateType = info.DelegateType; if (delegateType == null) { delegateType = info.MakeDelegateType(returnType, arg0, arg1); } return DynamicExpression.Make(returnType, delegateType, binder, arg0, arg1); } ///DelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ////// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1, Expression arg2) { ContractUtils.RequiresNotNull(binder, "binder"); ValidateDynamicArgument(arg0); ValidateDynamicArgument(arg1); ValidateDynamicArgument(arg2); DelegateHelpers.TypeInfo info = DelegateHelpers.GetNextTypeInfo( returnType, DelegateHelpers.GetNextTypeInfo( arg2.Type, DelegateHelpers.GetNextTypeInfo( arg1.Type, DelegateHelpers.GetNextTypeInfo( arg0.Type, DelegateHelpers.NextTypeInfo(typeof(CallSite)) ) ) ) ); Type delegateType = info.DelegateType; if (delegateType == null) { delegateType = info.MakeDelegateType(returnType, arg0, arg1, arg2); } return DynamicExpression.Make(returnType, delegateType, binder, arg0, arg1, arg2); } ///DelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ////// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The first argument to the dynamic operation. /// The second argument to the dynamic operation. /// The third argument to the dynamic operation. /// The fourth argument to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, Expression arg0, Expression arg1, Expression arg2, Expression arg3) { ContractUtils.RequiresNotNull(binder, "binder"); ValidateDynamicArgument(arg0); ValidateDynamicArgument(arg1); ValidateDynamicArgument(arg2); ValidateDynamicArgument(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; if (delegateType == null) { delegateType = info.MakeDelegateType(returnType, arg0, arg1, arg2, arg3); } return DynamicExpression.Make(returnType, delegateType, binder, arg0, arg1, arg2, arg3); } ///DelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ////// Creates a /// The runtime binder for the dynamic operation. /// The result type of the dynamic expression. /// The arguments to the dynamic operation. ///that represents a dynamic operation bound by the provided . /// /// A ///that has equal to /// Dynamic and has the ///Binder and ///Arguments set to the specified values. ////// The public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, IEnumerableDelegateType property of the /// result will be inferred from the types of the arguments and the specified return type. ///arguments) { ContractUtils.RequiresNotNull(arguments, "arguments"); ContractUtils.RequiresNotNull(returnType, "returnType"); var args = arguments.ToReadOnly(); ContractUtils.RequiresNotEmpty(args, "args"); return MakeDynamic(binder, returnType, args); } private static DynamicExpression MakeDynamic(CallSiteBinder binder, Type returnType, ReadOnlyCollection args) { ContractUtils.RequiresNotNull(binder, "binder"); for (int i = 0; i < args.Count; i++) { Expression arg = args[i]; ValidateDynamicArgument(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); } } private static void ValidateDynamicArgument(Expression arg) { RequiresCanRead(arg, "arguments"); var type = arg.Type; ContractUtils.RequiresNotNull(type, "type"); TypeUtils.ValidateType(type); if (type == typeof(void)) throw Error.ArgumentTypeCannotBeVoid(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ToolStripItemClickedEventArgs.cs
- EventHandlerList.cs
- DynamicExpression.cs
- XPathException.cs
- _NestedMultipleAsyncResult.cs
- EventSetterHandlerConverter.cs
- BaseProcessor.cs
- MdbDataFileEditor.cs
- PreviewKeyDownEventArgs.cs
- HttpCookiesSection.cs
- PolyLineSegmentFigureLogic.cs
- OleDbRowUpdatingEvent.cs
- CryptoKeySecurity.cs
- TimeManager.cs
- DataSourceXmlAttributeAttribute.cs
- EmbeddedObject.cs
- BinaryParser.cs
- ProcessProtocolHandler.cs
- NameValueFileSectionHandler.cs
- StreamBodyWriter.cs
- AliasedSlot.cs
- XmlDataSourceView.cs
- CardSpaceShim.cs
- XmlCharacterData.cs
- JsonObjectDataContract.cs
- BinaryFormatterSinks.cs
- AncillaryOps.cs
- CroppedBitmap.cs
- ListView.cs
- DummyDataSource.cs
- XmlSchemaObject.cs
- TemplateControlBuildProvider.cs
- FlowDocumentReader.cs
- AttributeUsageAttribute.cs
- WeakReferenceEnumerator.cs
- SimpleTableProvider.cs
- EntityViewContainer.cs
- ITextView.cs
- ControlValuePropertyAttribute.cs
- XMLDiffLoader.cs
- ReadOnlyHierarchicalDataSource.cs
- PropertyDescriptorGridEntry.cs
- Number.cs
- ModelService.cs
- TextDecorations.cs
- RelationalExpressions.cs
- PagedDataSource.cs
- Light.cs
- SqlClientMetaDataCollectionNames.cs
- BamlRecordWriter.cs
- CaseInsensitiveOrdinalStringComparer.cs
- DrawListViewItemEventArgs.cs
- shaperfactoryquerycachekey.cs
- Parser.cs
- MobileComponentEditorPage.cs
- ArraySortHelper.cs
- RoutedEventArgs.cs
- HwndAppCommandInputProvider.cs
- CompiledQuery.cs
- RectangleGeometry.cs
- DocumentSchemaValidator.cs
- SimpleFileLog.cs
- XsltSettings.cs
- StaticDataManager.cs
- _BaseOverlappedAsyncResult.cs
- ClearCollection.cs
- ResolveMatchesApril2005.cs
- RecipientIdentity.cs
- StringSorter.cs
- SchemaElement.cs
- ContainerUIElement3D.cs
- TypeConverterHelper.cs
- columnmapkeybuilder.cs
- SafeNativeHandle.cs
- ReadOnlyDataSource.cs
- ScriptControlDescriptor.cs
- ObjectManager.cs
- PageCatalogPart.cs
- PageRanges.cs
- DataGridViewAutoSizeModeEventArgs.cs
- XmlTextWriter.cs
- CustomTypeDescriptor.cs
- bindurihelper.cs
- XmlSerializationReader.cs
- UnsafeNativeMethods.cs
- _AutoWebProxyScriptWrapper.cs
- ContextMarshalException.cs
- FlowLayoutSettings.cs
- DataKeyCollection.cs
- DataKeyArray.cs
- SqlFunctionAttribute.cs
- Serializer.cs
- AutomationPattern.cs
- AutomationPropertyInfo.cs
- CellCreator.cs
- CompositeActivityValidator.cs
- DelayedRegex.cs
- DbDataAdapter.cs
- SystemIPInterfaceStatistics.cs
- SQLMembershipProvider.cs