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
- OLEDB_Enum.cs
- PresentationAppDomainManager.cs
- Setter.cs
- X509CertificateCollection.cs
- ValidationPropertyAttribute.cs
- MessageQueueCriteria.cs
- SingleObjectCollection.cs
- SqlParameterizer.cs
- DocumentPageTextView.cs
- InputBinding.cs
- MessagePropertyFilter.cs
- SqlTypeConverter.cs
- DataServiceHostFactory.cs
- IRCollection.cs
- GiveFeedbackEvent.cs
- X500Name.cs
- ConstructorBuilder.cs
- SslStream.cs
- DoubleLink.cs
- MultiAsyncResult.cs
- SyntaxCheck.cs
- _Win32.cs
- SQLStringStorage.cs
- PropertyPath.cs
- ServiceProviders.cs
- SecurityHelper.cs
- TableColumnCollection.cs
- Oid.cs
- StickyNoteHelper.cs
- PrintControllerWithStatusDialog.cs
- PathSegmentCollection.cs
- FlowSwitch.cs
- XmlQueryCardinality.cs
- UnsafeNativeMethods.cs
- COM2EnumConverter.cs
- CompoundFileReference.cs
- ProfilePropertyNameValidator.cs
- XmlCountingReader.cs
- Speller.cs
- MULTI_QI.cs
- DataGridViewImageCell.cs
- PrintDocument.cs
- UrlPropertyAttribute.cs
- WebPartTransformerAttribute.cs
- FontClient.cs
- RegexGroup.cs
- QilValidationVisitor.cs
- EdmEntityTypeAttribute.cs
- Blend.cs
- XmlSchemaImporter.cs
- RealProxy.cs
- GridViewActionList.cs
- OrthographicCamera.cs
- PerfCounters.cs
- ItemType.cs
- StateBag.cs
- AggregateNode.cs
- TranslateTransform.cs
- EventSchemaTraceListener.cs
- DefaultAutoFieldGenerator.cs
- HttpChannelBindingToken.cs
- CompilationLock.cs
- HttpRuntime.cs
- UiaCoreTypesApi.cs
- SoapProtocolImporter.cs
- PathFigure.cs
- BindingMemberInfo.cs
- PackWebRequest.cs
- Control.cs
- BaseTemplateCodeDomTreeGenerator.cs
- XmlSchemaSimpleContentExtension.cs
- WebPartManagerInternals.cs
- RelationshipDetailsCollection.cs
- ProtocolReflector.cs
- Trigger.cs
- BeginCreateSecurityTokenRequest.cs
- RuleProcessor.cs
- PropertyStore.cs
- TableLayoutStyleCollection.cs
- CookieParameter.cs
- Parser.cs
- DataSourceView.cs
- TiffBitmapEncoder.cs
- ClientOptions.cs
- CompositeDataBoundControl.cs
- CommittableTransaction.cs
- AnnotationComponentChooser.cs
- DbModificationClause.cs
- EndPoint.cs
- WinFormsSecurity.cs
- CustomAttribute.cs
- ForceCopyBuildProvider.cs
- WebPartConnectionsEventArgs.cs
- ElasticEase.cs
- PeerApplication.cs
- ConfigPathUtility.cs
- ProfilePropertySettings.cs
- PropertyBuilder.cs
- FileRegion.cs
- SimpleHandlerFactory.cs