Last active
January 7, 2017 18:25
-
-
Save neikeq/079e78bc3fded058e14ea8786d25ca7d to your computer and use it in GitHub Desktop.
Too bad this is not supported on iOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Dynamic; | |
| using System.Linq.Expressions; | |
| using System.Collections.Generic; | |
| using System.Reflection; | |
| namespace DynamicTest | |
| { | |
| class MainClass | |
| { | |
| public static void Main(string[] args) | |
| { | |
| dynamic node = new Node(); | |
| Console.WriteLine(node.set_pos(2)); | |
| Console.WriteLine(node.advice = "okthx"); | |
| Console.WriteLine(node.index); | |
| } | |
| } | |
| class Node : IDynamicMetaObjectProvider | |
| { | |
| public Node() | |
| { | |
| } | |
| DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) | |
| { | |
| return new MuyExpando(parameter, this); | |
| } | |
| public object get(string name) | |
| { | |
| Console.WriteLine("get " + name); | |
| return 84; // whatever | |
| } | |
| public object set(string name, object value) | |
| { | |
| Console.WriteLine("set " + name + " to " + value); | |
| return get(name); | |
| } | |
| public object call(string name, params object[] value) | |
| { | |
| var ret = 2.5f; | |
| Console.WriteLine("call " + name + " with " + value.Length + " args"); | |
| return ret; | |
| } | |
| class MuyExpando : DynamicMetaObject | |
| { | |
| public MuyExpando(Expression expression, Node value) | |
| : base(expression, BindingRestrictions.Empty, value) | |
| { | |
| } | |
| public override DynamicMetaObject BindGetMember(GetMemberBinder binder) | |
| { | |
| var self = Expression.Convert(Expression, LimitType); | |
| var arguments = new Expression[] | |
| { | |
| Expression.Constant(binder.Name) | |
| }; | |
| Expression expression = Expression.Call(self, typeof(Node).GetMethod("get", BindingFlags.Public | BindingFlags.Instance), arguments); | |
| return new DynamicMetaObject(expression, BindingRestrictions.GetTypeRestriction(Expression, LimitType)); | |
| } | |
| public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args) | |
| { | |
| var self = Expression.Convert(Expression, LimitType); | |
| var arguments = new Expression[] | |
| { | |
| Expression.Constant(binder.Name), | |
| Expression.Constant(new object[0]) | |
| }; | |
| Expression expression = Expression.Call(self, typeof(Node).GetMethod("call", BindingFlags.Public | BindingFlags.Instance), arguments); | |
| return new DynamicMetaObject(expression, BindingRestrictions.GetTypeRestriction(Expression, LimitType)); | |
| } | |
| public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value) | |
| { | |
| var self = Expression.Convert(Expression, LimitType); | |
| var arguments = new Expression[] | |
| { | |
| Expression.Constant(binder.Name), | |
| Expression.Convert(value.Expression, typeof(object)) | |
| }; | |
| Expression expression = Expression.Call(self, typeof(Node).GetMethod("set", BindingFlags.Public | BindingFlags.Instance), arguments); | |
| return new DynamicMetaObject(expression, BindingRestrictions.GetTypeRestriction(Expression, LimitType)); | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment