Skip to content

Instantly share code, notes, and snippets.

@neikeq
Last active January 7, 2017 18:25
Show Gist options
  • Select an option

  • Save neikeq/079e78bc3fded058e14ea8786d25ca7d to your computer and use it in GitHub Desktop.

Select an option

Save neikeq/079e78bc3fded058e14ea8786d25ca7d to your computer and use it in GitHub Desktop.
Too bad this is not supported on iOS
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