internal override Expression GetExpression(List <ParameterExpression> parameters, Dictionary <string, ConstantExpression> locals, List <DataContainer> dataContainers, Type dynamicContext, LabelTarget label, bool requiresReturnValue = true) { ParameterInfo[] pars = Method.GetParameters(); Expression[] args = new Expression[pars.Length]; for (int i = 0; i < pars.Length; ++i) { if (i < Arguments.Arguments.Length) { CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, pars[i].ParameterType, dynamicContext ?? typeof(object)); args[i] = Expression.Dynamic(binder, pars[i].ParameterType, Arguments.Arguments[i].GetExpression(parameters, locals, dataContainers, dynamicContext, label)); } else { CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, pars[i].ParameterType, dynamicContext ?? typeof(object)); args[i] = Expression.Dynamic(binder, pars[i].ParameterType, Expression.Constant(pars[i].DefaultValue, typeof(object))); } } var exp = Expression.Call(Method, args); if (requiresReturnValue) { return(Expression.Convert(exp, typeof(object))); } return(exp); }
/// <summary> /// Provides implementation for binary operations. Classes derived from the <see cref="T:System.Dynamic.DynamicObject"/> class can override this method to specify dynamic behavior for operations such as addition and multiplication. /// </summary> /// <returns><c>true</c> if the operation is successful; otherwise, <c>false</c>. If this method returns <c>false</c>, the run-time binder of the language determines the behavior. (In most cases, a language-specific run-time exception is thrown.)</returns> /// <param name="binder">Provides information about the binary operation. The binder.Operation property returns an <see cref="T:System.Linq.Expressions.ExpressionType"/> object. For example, for the sum = first + second statement, where first and second are derived from the DynamicObject class, binder.Operation returns ExpressionType.Add.</param><param name="arg">The right operand for the binary operation. For example, for the sum = first + second statement, where first and second are derived from the DynamicObject class, <paramref name="arg"/> is equal to second.</param><param name="result">The result of the binary operation.</param> public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result) { object resultOfCast; result = null; if (binder.Operation != ExpressionType.Equal) { return(false); } var convert = Binder.Convert(CSharpBinderFlags.None, arg.GetType(), typeof(ElasticsearchDynamicValue)); if (!TryConvert((ConvertBinder)convert, out resultOfCast)) { return(false); } result = (resultOfCast == null) ? Equals(arg, resultOfCast) : resultOfCast.Equals(arg); return(true); }
internal static object InvokeConvertCallSite(object target, bool explict, Type type, Type context, ref CallSite callSite) { if (callSite == null) { LazyBinder binder = () => { var flags = explict ? CSharpBinderFlags.ConvertExplicit : CSharpBinderFlags.None; return(Binder.Convert(flags, type, context)); }; Type binderType = typeof(ConvertBinder); var func = BuildProxy.GenerateCallSiteFuncType(new Type[] {}, type); callSite = CreateCallSite(func, binderType, binder, explict ? Invocation.ExplicitConvertBinderName : Invocation.ImplicitConvertBinderName, context); } dynamic theDynamicCallSite = callSite; return(theDynamicCallSite.OriginalTarget(callSite, target)); }
private static void AttemptExplicitCast <TFrom, TTo>() { // based on the IL generated from // var x = (TTo)(dynamic)default(TFrom); var binder = CSharpBinder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(TTo), typeof(ConversionHelper)); var callSite = CallSite <Func <CallSite, TFrom, TTo> > .Create(binder); callSite.Target(callSite, default(TFrom)); }
private static TTo AttemptExplicitCast <TFrom, TTo>(TFrom value) { // based on the IL generated from //var x = (TTo)(dynamic)value; var binder = CSharpBinder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(TTo), typeof(TypeHelper)); var callSite = CallSite <Func <CallSite, TFrom, TTo> > .Create(binder); //dynamic tDynCallSite = callSite; return(callSite.Target(callSite, value)); }
internal override Expression GetExpression(List <ParameterExpression> parameters, Dictionary <string, ConstantExpression> locals, List <DataContainer> dataContainers, Type dynamicContext, LabelTarget label) { Expression exp; if (ConstructorType != null) { if (Constructor != null) { ParameterInfo[] info = Constructor.GetParameters(); List <Expression> args = new List <Expression>(); for (int i = 0; i < info.Length; ++i) { args.Add(Expression.Dynamic(Binder.Convert(CSharpBinderFlags.None, info[i].ParameterType, dynamicContext ?? typeof(object)), info[i].ParameterType, Arguments.Arguments[i].GetExpression(parameters, locals, dataContainers, dynamicContext, label))); } exp = Expression.New(Constructor, args); } else { exp = Expression.New(ConstructorType); } if (Initializers != null) { if (Initializers.Arguments.Any(token => token is AssignmentToken)) { Func <MemberInfo, Type> getType = mem => mem is FieldInfo ? (mem as FieldInfo).FieldType : (mem as PropertyInfo).PropertyType; var inits = Initializers.Arguments.Cast <AssignmentToken>().Select(token => new Tuple <MemberInfo, Expression>(token.Member, Expression.Dynamic(Binder.Convert(CSharpBinderFlags.None, getType(token.Member), dynamicContext ?? typeof(object)), getType(token.Member), token.Value.GetExpression(parameters, locals, dataContainers, dynamicContext, label)))); exp = Expression.MemberInit(exp as NewExpression, inits.Select(init => (MemberBinding)Expression.Bind(init.Item1, init.Item2))); } else { exp = Expression.ListInit(exp as NewExpression, ConvertInitializers(Initializers, parameters, locals, dataContainers, dynamicContext, null, label).Cast <ElementInit>()); } } } else { if (Initializers != null) { CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, ArrayType, dynamicContext ?? typeof(object)); exp = Expression.NewArrayInit(ArrayType, Initializers.Arguments.Select(token => Expression.Dynamic(binder, ArrayType, token.GetExpression(parameters, locals, dataContainers, dynamicContext, label)))); } else { CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, typeof(int), dynamicContext ?? typeof(object)); exp = Expression.NewArrayBounds(ArrayType, Arguments.Arguments.Select(token => Expression.Dynamic(binder, typeof(int), token.GetExpression(parameters, locals, dataContainers, dynamicContext, label)))); } } return(Expression.Convert(exp, typeof(object))); }
internal override Expression GetExpression(List <ParameterExpression> parameters, Dictionary <string, ConstantExpression> locals, List <DataContainer> dataContainers, Type dynamicContext, LabelTarget label, bool requiresReturnValue = true) { var value = Value.GetExpression(parameters, locals, dataContainers, dynamicContext, label); if (Target is InstanceMemberToken) { CallSiteBinder binder = Binder.SetMember(CSharpBinderFlags.None, (Target as InstanceMemberToken).MemberName, dynamicContext ?? typeof(object), new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }); return(Expression.Dynamic(binder, typeof(object), (Target as InstanceMemberToken).Target.GetExpression(parameters, locals, dataContainers, dynamicContext, label), value)); } else { var type = (Target as StaticMemberToken).Member is PropertyInfo ? ((Target as StaticMemberToken).Member as PropertyInfo).PropertyType : ((Target as StaticMemberToken).Member as FieldInfo).FieldType; CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, type, dynamicContext ?? typeof(object)); return(Expression.Convert(Expression.Assign(Expression.MakeMemberAccess(null, (Target as StaticMemberToken).Member), Expression.Dynamic(binder, type, value)), typeof(object))); } }
public object AccessValueElementTest(string elementName, object value, Type type) { XElement element = new XElement(elementName, value); dynamic dynamicElement = element.AsDynamic(); CallSiteBinder callsiteBinder = Binder.Convert(CSharpBinderFlags.None, type, typeof(DynamicXElementReader)); //-----------------------------------------------------------------------------------// // Creating Func<CallSite, object, Type> //-----------------------------------------------------------------------------------// // For type "int" this code is equivalent to: // Type constructedFuncType = typeof(Func<CallSite, object, int); Type openFuncType = typeof(Func <, ,>); Type constructedFuncType = openFuncType.MakeGenericType( typeof(CallSite), typeof(object), type); //-----------------------------------------------------------------------------------// // Creating CallSite<Func<CallSite, object, Type>> //-----------------------------------------------------------------------------------// // For type "int" this code is equivalent to: // Type constructedCallSiteType = typeof(CallSite<Func<CallSite, object, int>>); Type callSiteType = typeof(CallSite <>); Type constructedCallSiteType = callSiteType.MakeGenericType(constructedFuncType); //-----------------------------------------------------------------------------------// // var callSite = CallSite<Func<CallSite, object, int>>.Create(callSiteBinder); //-----------------------------------------------------------------------------------// var method = constructedCallSiteType.GetMethod("Create", BindingFlags.Static | BindingFlags.Public); CallSite callSite = (CallSite)method.Invoke(null, new object[] { callsiteBinder }); //-----------------------------------------------------------------------------------// // int actual = callSite.Target(callSite, dynamicElement); //-----------------------------------------------------------------------------------// FieldInfo targetFieldInfo = callSite.GetType().GetField("Target"); object target = targetFieldInfo.GetValue(callSite); // target is underlying delegate instance of type: Func<CallSite, object, int> var targetMethod = target.GetType().GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public); object actual = targetMethod.Invoke(target, new object[] { callSite, dynamicElement }); Console.WriteLine("Name: {0}, Value: {1}, Type: {2}", elementName, value, type); Console.WriteLine("Actual value: {0}", actual); return(actual); }
private static bool AttemptExplicitCast <TFrom, TTo>() { // based on the IL generated from // var x = (TTo)(dynamic)default(TFrom); try { var binder = CSharpBinder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(TTo), typeof(ConversionHelper)); var callSite = CallSite <Func <CallSite, TFrom, TTo> > .Create(binder); callSite.Target(callSite, default(TFrom)); return(true); } catch (RuntimeBinderException ex) { return(!ex.Message.EndsWith(" konvertiert werden.")); } }
public void AccessValueWithBinderTest() { XElement element = new XElement("name", 1); dynamic dynamicElement = element.AsDynamic(); // Following lines are almost equivalent (except caching) // to following: // int actual = (int)dynamicElement; var callsiteBinder = Binder.Convert(CSharpBinderFlags.None, typeof(int), typeof(DynamicXElementReader)); CallSite <Func <CallSite, object, int> > callSite = CallSite <Func <CallSite, object, int> > .Create(callsiteBinder); int actual = callSite.Target(callSite, dynamicElement); Assert.That(actual, Is.EqualTo(1)); }
internal static object InvokeConvertCallSite(object target, bool explict, Type type, Type context, ref CallSite callSite) { if (callSite == null) { LazyBinder tBinder = () => { var tFlags = explict ? CSharpBinderFlags.ConvertExplicit : CSharpBinderFlags.None; return(Binder.Convert(tFlags, type, context)); }; Type tBinderType = typeof(ConvertBinder); var tFunc = typeof(Func <, ,>).MakeGenericType(typeof(CallSite), typeof(object), type); callSite = CreateCallSite(tFunc, tBinderType, Unknown, tBinder, explict ? Invocation.ExplicitConvertBinderName : Invocation.ImplicitConvertBinderName, context); } dynamic tDynCallSite = callSite; return(tDynCallSite.Target(callSite, target)); }
private IEnumerable <object> ConvertInitializers(ArgumentListToken arguments, List <ParameterExpression> parameters, Dictionary <string, ConstantExpression> locals, List <DataContainer> dataContainers, Type dynamicContext, Type[] expectedTypes, LabelTarget label) { foreach (TokenBase token in arguments.Arguments) { if (token is ArgumentListToken) { MethodInfo add = Constructor.DeclaringType.GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(m => m.Name == "Add" && m.GetParameters().Length == (token as ArgumentListToken).Arguments.Length); int i = 0; Expression[] exps = new Expression[add.GetParameters().Length]; foreach (ParameterInfo info in add.GetParameters()) { CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, info.ParameterType, dynamicContext); exps[i] = Expression.Dynamic(binder, info.ParameterType, (token as ArgumentListToken).Arguments[i++].GetExpression(parameters, locals, dataContainers, dynamicContext, label)); } yield return(Expression.ElementInit(add, exps)); } else { MethodInfo add = Constructor.DeclaringType.GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(m => m.Name == "Add" && m.GetParameters().Length == 1); CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, add.GetParameters()[0].ParameterType, dynamicContext); yield return(Expression.ElementInit(add, Expression.Dynamic(binder, add.GetParameters()[0].ParameterType, token.GetExpression(parameters, locals, dataContainers, dynamicContext, label)))); } } }
internal override Expression GetExpression(List <ParameterExpression> parameters, Dictionary <string, ConstantExpression> locals, List <DataContainer> dataContainers, Type dynamicContext, LabelTarget label) { if (Lambda) { List <Tuple <string, Type> > pars = new List <Tuple <string, Type> >(); foreach (TokenBase token in Arguments.Arguments) { if (token is TypeCastToken) { pars.Add(new Tuple <string, Type>(((token as TypeCastToken).Target as ParameterToken).Name, (token as TypeCastToken).TargetType)); } else { pars.Add(new Tuple <string, Type>((token as ParameterToken).Name, typeof(object))); } } Dictionary <string, ConstantExpression> subLocals = new Dictionary <string, ConstantExpression>(); foreach (var tuple in pars) { var container = new DataContainer(); subLocals.Add(tuple.Item1, Expression.Constant(container)); dataContainers.Add(container); } List <ParameterExpression> parExps = new List <ParameterExpression>(); Expression exp = Value.GetExpression(parExps, subLocals, dataContainers, dynamicContext, label); if (parExps.Count != 0) { foreach (ParameterExpression par in parExps) { if (!(parameters.Any(p => p.Name == par.Name) || locals.Any(l => l.Key == par.Name))) { parameters.Add(par); } var container = new DataContainer(); subLocals.Add(par.Name, Expression.Constant(container)); dataContainers.Add(container); } parExps.Clear(); exp = Value.GetExpression(parExps, subLocals, dataContainers, dynamicContext, label); } foreach (var tuple in pars) { parExps.Add(Expression.Parameter(tuple.Item2, tuple.Item1)); } CallSiteBinder binder = Binder.Convert(CSharpBinderFlags.None, Value.ReturnType, dynamicContext); Expression block = Expression.Block(subLocals.Zip(parExps, (l, p) => Expression.Assign(Expression.Property(l.Value, "Value"), Expression.Convert(p, typeof(object)))).Concat(new Expression[] { Expression.Dynamic(binder, Value.ReturnType, exp) })); Type type = funcTypes[pars.Count].MakeGenericType(pars.Select(t => t.Item2).Concat(new[] { Value.ReturnType }).ToArray()); MethodInfo method = typeof(Expression).GetMethods().FirstOrDefault(m => m.Name == "Lambda" && m.IsGenericMethod && m.GetParameters().Length == 2).MakeGenericMethod(type); object func = ((dynamic)method.Invoke(null, new object[] { block, parExps.ToArray() })).Compile(); Expression ret = Expression.Block(subLocals.Skip(parExps.Count).Select(kvp => Expression.Assign(Expression.Property(kvp.Value, "Value"), parameters.Select(p => new Tuple <string, Expression>(p.Name, p)).Concat(locals.Select(k => new Tuple <string, Expression>(k.Key, Expression.Property(k.Value, "Value")))).First(p => p.Item1 == kvp.Key).Item2)).Concat(new [] { Expression.Constant(func) as Expression })); return(ret); } else { List <ConstantExpression> newLocals = new List <ConstantExpression>(); foreach (var arg in Arguments.Arguments.Cast <AssignmentToken>()) { if (locals.Any(name => name.Key == arg.Name)) { throw new Exception("Duplicate local variable name \"" + arg.Name + "\" found."); } var container = new DataContainer(); var value = Expression.Constant(container); dataContainers.Add(container); newLocals.Add(value); locals.Add(arg.Name, value); } IEnumerable <BinaryExpression> assignments = Arguments.Arguments.Cast <AssignmentToken>().Zip(newLocals, (t, l) => Expression.Assign(Expression.Property(l, "Value"), t.Value.GetExpression(parameters, locals, dataContainers, dynamicContext, label))); Expression ret = Expression.Block(assignments.Cast <Expression>().Concat(new Expression[] { Value.GetExpression(parameters, locals, dataContainers, dynamicContext, label) })); foreach (var arg in Arguments.Arguments.Cast <AssignmentToken>()) { locals.Remove(arg.Name); } return(ret); } }
public static K TryEvalCast <T, K>(T obj, Type type, CSharpBinderFlags kind, Type accessibilityContext) { var site = CallSite <Func <CallSite, T, K> > .Create(Binder.Convert(kind, type, accessibilityContext)); return(site.Target(site, obj)); }