mscorlib(4.0.0.0) API with additions
DynamicMetaObjectBinder.cs
2 using System.Dynamic.Utils;
7 
8 namespace System.Dynamic
9 {
11  [global::__DynamicallyInvokable]
12  public abstract class DynamicMetaObjectBinder : CallSiteBinder
13  {
14  private static readonly Type ComObjectType = typeof(object).Assembly.GetType("System.__ComObject");
15 
18  [global::__DynamicallyInvokable]
19  public virtual Type ReturnType
20  {
21  [global::__DynamicallyInvokable]
22  get
23  {
24  return typeof(object);
25  }
26  }
27 
28  internal virtual bool IsStandardBinder => false;
29 
31  [global::__DynamicallyInvokable]
33  {
34  }
35 
41  [global::__DynamicallyInvokable]
42  public sealed override Expression Bind(object[] args, ReadOnlyCollection<ParameterExpression> parameters, LabelTarget returnLabel)
43  {
44  ContractUtils.RequiresNotNull(args, "args");
45  ContractUtils.RequiresNotNull(parameters, "parameters");
46  ContractUtils.RequiresNotNull(returnLabel, "returnLabel");
47  if (args.Length == 0)
48  {
49  throw Error.OutOfRange("args.Length", 1);
50  }
51  if (parameters.Count == 0)
52  {
53  throw Error.OutOfRange("parameters.Count", 1);
54  }
55  if (args.Length != parameters.Count)
56  {
57  throw new ArgumentOutOfRangeException("args");
58  }
59  Type type;
60  if (IsStandardBinder)
61  {
62  type = ReturnType;
63  if (returnLabel.Type != typeof(void) && !TypeUtils.AreReferenceAssignable(returnLabel.Type, type))
64  {
65  throw Error.BinderNotCompatibleWithCallSite(type, this, returnLabel.Type);
66  }
67  }
68  else
69  {
70  type = returnLabel.Type;
71  }
72  DynamicMetaObject dynamicMetaObject = DynamicMetaObject.Create(args[0], parameters[0]);
73  DynamicMetaObject[] args2 = CreateArgumentMetaObjects(args, parameters);
74  DynamicMetaObject dynamicMetaObject2 = Bind(dynamicMetaObject, args2);
75  if (dynamicMetaObject2 == null)
76  {
77  throw Error.BindingCannotBeNull();
78  }
79  Expression expression = dynamicMetaObject2.Expression;
80  BindingRestrictions restrictions = dynamicMetaObject2.Restrictions;
81  if (type != typeof(void) && !TypeUtils.AreReferenceAssignable(type, expression.Type))
82  {
83  if (dynamicMetaObject.Value is IDynamicMetaObjectProvider)
84  {
85  throw Error.DynamicObjectResultNotAssignable(expression.Type, dynamicMetaObject.Value.GetType(), this, type);
86  }
87  throw Error.DynamicBinderResultNotAssignable(expression.Type, this, type);
88  }
89  if (IsStandardBinder && args[0] is IDynamicMetaObjectProvider && restrictions == BindingRestrictions.Empty)
90  {
91  throw Error.DynamicBindingNeedsRestrictions(dynamicMetaObject.Value.GetType(), this);
92  }
93  restrictions = AddRemoteObjectRestrictions(restrictions, args, parameters);
94  if (expression.NodeType != ExpressionType.Goto)
95  {
96  expression = Expression.Return(returnLabel, expression);
97  }
98  if (restrictions != BindingRestrictions.Empty)
99  {
100  expression = Expression.IfThen(restrictions.ToExpression(), expression);
101  }
102  return expression;
103  }
104 
105  private static DynamicMetaObject[] CreateArgumentMetaObjects(object[] args, ReadOnlyCollection<ParameterExpression> parameters)
106  {
107  DynamicMetaObject[] array;
108  if (args.Length != 1)
109  {
110  array = new DynamicMetaObject[args.Length - 1];
111  for (int i = 1; i < args.Length; i++)
112  {
113  array[i - 1] = DynamicMetaObject.Create(args[i], parameters[i]);
114  }
115  }
116  else
117  {
118  array = DynamicMetaObject.EmptyMetaObjects;
119  }
120  return array;
121  }
122 
123  private static BindingRestrictions AddRemoteObjectRestrictions(BindingRestrictions restrictions, object[] args, ReadOnlyCollection<ParameterExpression> parameters)
124  {
125  for (int i = 0; i < parameters.Count; i++)
126  {
127  ParameterExpression parameterExpression = parameters[i];
128  MarshalByRefObject marshalByRefObject = args[i] as MarshalByRefObject;
129  if (marshalByRefObject != null && !IsComObject(marshalByRefObject))
130  {
131  BindingRestrictions restrictions2 = (!RemotingServices.IsObjectOutOfAppDomain(marshalByRefObject)) ? BindingRestrictions.GetExpressionRestriction(Expression.AndAlso(Expression.NotEqual(parameterExpression, Expression.Constant(null)), Expression.Not(Expression.Call(typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), parameterExpression)))) : BindingRestrictions.GetExpressionRestriction(Expression.AndAlso(Expression.NotEqual(parameterExpression, Expression.Constant(null)), Expression.Call(typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), parameterExpression)));
132  restrictions = restrictions.Merge(restrictions2);
133  }
134  }
135  return restrictions;
136  }
137 
142  [global::__DynamicallyInvokable]
143  public abstract DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args);
144 
148  [global::__DynamicallyInvokable]
150  {
151  return Expression.Goto(CallSiteBinder.UpdateLabel, type);
152  }
153 
158  [global::__DynamicallyInvokable]
160  {
161  ContractUtils.RequiresNotNull(target, "target");
162  if (args == null)
163  {
164  return MakeDeferred(target.Restrictions, target);
165  }
166  return MakeDeferred(target.Restrictions.Merge(BindingRestrictions.Combine(args)), args.AddFirst(target));
167  }
168 
172  [global::__DynamicallyInvokable]
174  {
175  return MakeDeferred(BindingRestrictions.Combine(args), args);
176  }
177 
178  private DynamicMetaObject MakeDeferred(BindingRestrictions rs, params DynamicMetaObject[] args)
179  {
180  Expression[] expressions = DynamicMetaObject.GetExpressions(args);
181  Type delegateType = DelegateHelpers.MakeDeferredSiteDelegate(args, ReturnType);
182  return new DynamicMetaObject(DynamicExpression.Make(ReturnType, delegateType, this, new TrueReadOnlyCollection<Expression>(expressions)), rs);
183  }
184 
185  private static bool IsComObject(object obj)
186  {
187  if (obj != null)
188  {
189  return ComObjectType.IsAssignableFrom(obj.GetType());
190  }
191  return false;
192  }
193  }
194 }
Represents a dynamic object, that can have its operations bound at runtime.
Type Type
The type of value that is passed when jumping to the label (or T:System.Void if no value should be pa...
Definition: LabelTarget.cs:27
DynamicMetaObject Defer(DynamicMetaObject target, params DynamicMetaObject[] args)
Defers the binding of the operation until later time when the runtime values of all dynamic operation...
Represents the dynamic binding and a binding logic of an object participating in the dynamic binding.
Definition: __Canon.cs:3
The exception that is thrown when the value of an argument is outside the allowable range of values a...
int Count
Gets the number of elements contained in the T:System.Collections.ObjectModel.ReadOnlyCollection`1 in...
object Value
The runtime value represented by this T:System.Dynamic.DynamicMetaObject.
Used to represent the target of a T:System.Linq.Expressions.GotoExpression.
Definition: LabelTarget.cs:5
static readonly BindingRestrictions Empty
Represents an empty set of binding restrictions. This field is read only.
BindingRestrictions Merge(BindingRestrictions restrictions)
Merges the set of binding restrictions with the current binding restrictions.
Expression Expression
The expression representing the T:System.Dynamic.DynamicMetaObject during the dynamic binding process...
static LabelTarget UpdateLabel
Gets a label that can be used to cause the binding to be updated. It indicates that the expression's ...
Provides the base class from which the classes that represent expression tree nodes are derived....
Definition: Expression.cs:17
static bool IsObjectOutOfAppDomain(object tp)
Returns a Boolean value that indicates whether the object specified by the given transparent proxy is...
BindingRestrictions Restrictions
The set of binding restrictions under which the binding is valid.
DynamicMetaObjectBinder()
Initializes a new instance of the T:System.Dynamic.DynamicMetaObjectBinder class.
abstract Assembly Assembly
Gets the T:System.Reflection.Assembly in which the type is declared. For generic types,...
Definition: Type.cs:131
Represents type declarations: class types, interface types, array types, value types,...
Definition: Type.cs:18
The dynamic call site binder that participates in the T:System.Dynamic.DynamicMetaObject binding prot...
sealed override Expression Bind(object[] args, ReadOnlyCollection< ParameterExpression > parameters, LabelTarget returnLabel)
Performs the runtime binding of the dynamic operation on a set of arguments.
Represents a named parameter expression.
ExpressionType
Describes the node types for the nodes of an expression tree.
Represents a set of binding restrictions on the T:System.Dynamic.DynamicMetaObject under which the dy...
Expression GetUpdateExpression(Type type)
Gets an expression that will cause the binding to be updated. It indicates that the expression's bind...
Class responsible for runtime binding of the dynamic operations on the dynamic call site.
Represents a dynamic operation.
static DynamicMetaObject Create(object value, Expression expression)
Creates a meta-object for the specified object.
static BindingRestrictions Combine(IList< DynamicMetaObject > contributingObjects)
Combines binding restrictions from the list of T:System.Dynamic.DynamicMetaObject instances into one ...
Provides several methods for using and publishing remoted objects and proxies. This class cannot be i...
DynamicMetaObject Defer(params DynamicMetaObject[] args)
Defers the binding of the operation until later time when the runtime values of all dynamic operation...
Expression ToExpression()
Creates the T:System.Linq.Expressions.Expression representing the binding restrictions.
virtual Type ReturnType
The result type of the operation.