using System;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using Microsoft.CSharp.RuntimeBinder;
namespace ConsoleApplication1
{
class TargetClass0
{
private void Call(int arg)
{
//実際呼び出されたか確認するため
Console.WriteLine("TargetClass0 is Called value:" + arg.ToString());
}
public int Value
{
get;
set;
}
}
class TargetClass1
{
public int Value;
public void Call(int arg)
{
//実際呼び出されたか確認するため
Console.WriteLine("TargetClass1 is Called value:" + arg.ToString());
}
}
class Program
{
static void SetProperty(dynamic d,int value)
{
d.Value = value;
}
static void InvokeDelegate(dynamic d, int value)
{
d(value);
}
static Expression<Action<object, int>> SetPropertyExpr()
{
var binder = Binder.SetMember(CSharpBinderFlags.ResultDiscarded, "Value", typeof(Program)
, new[]{CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None,"target"),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType,"arg")});
var targetExpr = Expression.Parameter(typeof(object), "target");
var paramExpr=Expression.Parameter(typeof(int),"arg");
var dynamicExpr = Expression.MakeDynamic(typeof(Action<CallSite, object, int>), binder, targetExpr, paramExpr);
return Expression.Lambda<Action<object, int>>(dynamicExpr,targetExpr, paramExpr);
}
static Expression<Func<object, int>> GetProertyExpr()
{
var getBinder = Binder.GetMember(CSharpBinderFlags.None, "Value", typeof(Program),
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, "Target") });
var convBinder = Binder.Convert(CSharpBinderFlags.None, typeof(int), typeof(Program));
var targetExpr = Expression.Parameter(typeof(object), "target");
var getExpr = Expression.Dynamic(getBinder, typeof(object), targetExpr);
var convExpr = Expression.Dynamic(convBinder, typeof(int), getExpr);
return Expression.Lambda<Func<object, int>>(convExpr, targetExpr);
}
static void Main(string[] args)
{
var setExpr = SetPropertyExpr();
var setContainer_ = setExpr.Compile();
var getExpr = GetProertyExpr();
var getContainer = getExpr.Compile();
var t0 = new TargetClass0();
var t1 = new TargetClass1();
Console.WriteLine("t0's Value is " + t0.Value);
Console.WriteLine("t1's Value is " + t1.Value);
Console.WriteLine();
Console.WriteLine();
setContainer_(t0, 100);
Console.WriteLine("t0's Value is " + getContainer(t0));
setContainer_(t1, 200);
Console.WriteLine("t1's Value is " + getContainer(t1));
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uTGlucS5FeHByZXNzaW9uczsKdXNpbmcgU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlczsKdXNpbmcgTWljcm9zb2Z0LkNTaGFycC5SdW50aW1lQmluZGVyOwoKbmFtZXNwYWNlIENvbnNvbGVBcHBsaWNhdGlvbjEKewoJY2xhc3MgVGFyZ2V0Q2xhc3MwCgl7CgkJcHJpdmF0ZSB2b2lkIENhbGwoaW50IGFyZykKCQl7CgkJCS8v5a6f6Zqb5ZG844Gz5Ye644GV44KM44Gf44GL56K66KqN44GZ44KL44Gf44KBCgkJCUNvbnNvbGUuV3JpdGVMaW5lKCJUYXJnZXRDbGFzczAgaXMgQ2FsbGVkIHZhbHVlOiIgKyBhcmcuVG9TdHJpbmcoKSk7CgkJfQoKCQlwdWJsaWMgaW50IFZhbHVlCgkJewoJCQlnZXQ7CgkJCXNldDsKCQl9Cgl9CgoJY2xhc3MgVGFyZ2V0Q2xhc3MxCgl7CgkJcHVibGljIGludCBWYWx1ZTsKCgkJcHVibGljIHZvaWQgQ2FsbChpbnQgYXJnKQoJCXsKCQkJLy/lrp/pmpvlkbzjgbPlh7rjgZXjgozjgZ/jgYvnorroqo3jgZnjgovjgZ/jgoEKCQkJQ29uc29sZS5Xcml0ZUxpbmUoIlRhcmdldENsYXNzMSBpcyBDYWxsZWQgdmFsdWU6IiArIGFyZy5Ub1N0cmluZygpKTsKCQl9CgoJfQoKCWNsYXNzIFByb2dyYW0KCXsKCQlzdGF0aWMgdm9pZCBTZXRQcm9wZXJ0eShkeW5hbWljIGQsaW50IHZhbHVlKQoJCXsKCQkJZC5WYWx1ZSA9IHZhbHVlOwoJCX0KCgkJc3RhdGljIHZvaWQgSW52b2tlRGVsZWdhdGUoZHluYW1pYyBkLCBpbnQgdmFsdWUpCgkJewoJCQlkKHZhbHVlKTsKCQl9CgoKCQlzdGF0aWMgRXhwcmVzc2lvbjxBY3Rpb248b2JqZWN0LCBpbnQ+PiBTZXRQcm9wZXJ0eUV4cHIoKQoJCXsKCQkJdmFyIGJpbmRlciA9IEJpbmRlci5TZXRNZW1iZXIoQ1NoYXJwQmluZGVyRmxhZ3MuUmVzdWx0RGlzY2FyZGVkLCAiVmFsdWUiLCB0eXBlb2YoUHJvZ3JhbSkKCQkJCSwgbmV3W117Q1NoYXJwQXJndW1lbnRJbmZvLkNyZWF0ZShDU2hhcnBBcmd1bWVudEluZm9GbGFncy5Ob25lLCJ0YXJnZXQiKSwKCQkJCQkJQ1NoYXJwQXJndW1lbnRJbmZvLkNyZWF0ZShDU2hhcnBBcmd1bWVudEluZm9GbGFncy5Vc2VDb21waWxlVGltZVR5cGUsImFyZyIpfSk7CgoJCQl2YXIgdGFyZ2V0RXhwciA9IEV4cHJlc3Npb24uUGFyYW1ldGVyKHR5cGVvZihvYmplY3QpLCAidGFyZ2V0Iik7CgkJCXZhciBwYXJhbUV4cHI9RXhwcmVzc2lvbi5QYXJhbWV0ZXIodHlwZW9mKGludCksImFyZyIpOwoKCQkJdmFyIGR5bmFtaWNFeHByID0gRXhwcmVzc2lvbi5NYWtlRHluYW1pYyh0eXBlb2YoQWN0aW9uPENhbGxTaXRlLCBvYmplY3QsIGludD4pLCBiaW5kZXIsIHRhcmdldEV4cHIsIHBhcmFtRXhwcik7CgoJCQlyZXR1cm4gRXhwcmVzc2lvbi5MYW1iZGE8QWN0aW9uPG9iamVjdCwgaW50Pj4oZHluYW1pY0V4cHIsdGFyZ2V0RXhwciwgcGFyYW1FeHByKTsKCgkJfQoKCQlzdGF0aWMgRXhwcmVzc2lvbjxGdW5jPG9iamVjdCwgaW50Pj4gR2V0UHJvZXJ0eUV4cHIoKQoJCXsKCQkJdmFyIGdldEJpbmRlciA9IEJpbmRlci5HZXRNZW1iZXIoQ1NoYXJwQmluZGVyRmxhZ3MuTm9uZSwgIlZhbHVlIiwgdHlwZW9mKFByb2dyYW0pLAoJCQkJbmV3W10geyBDU2hhcnBBcmd1bWVudEluZm8uQ3JlYXRlKENTaGFycEFyZ3VtZW50SW5mb0ZsYWdzLk5vbmUsICJUYXJnZXQiKSB9KTsKCgkJCXZhciBjb252QmluZGVyID0gQmluZGVyLkNvbnZlcnQoQ1NoYXJwQmluZGVyRmxhZ3MuTm9uZSwgdHlwZW9mKGludCksIHR5cGVvZihQcm9ncmFtKSk7CgoJCQl2YXIgdGFyZ2V0RXhwciA9IEV4cHJlc3Npb24uUGFyYW1ldGVyKHR5cGVvZihvYmplY3QpLCAidGFyZ2V0Iik7CgoJCQl2YXIgZ2V0RXhwciA9IEV4cHJlc3Npb24uRHluYW1pYyhnZXRCaW5kZXIsIHR5cGVvZihvYmplY3QpLCB0YXJnZXRFeHByKTsKCQkJdmFyIGNvbnZFeHByID0gRXhwcmVzc2lvbi5EeW5hbWljKGNvbnZCaW5kZXIsIHR5cGVvZihpbnQpLCBnZXRFeHByKTsKCgkJCXJldHVybiBFeHByZXNzaW9uLkxhbWJkYTxGdW5jPG9iamVjdCwgaW50Pj4oY29udkV4cHIsIHRhcmdldEV4cHIpOwoJCX0KCgoJCXN0YXRpYyB2b2lkIE1haW4oc3RyaW5nW10gYXJncykKCQl7CgoKCQkJdmFyIHNldEV4cHIgPSBTZXRQcm9wZXJ0eUV4cHIoKTsKCQkJdmFyIHNldENvbnRhaW5lcl8gPSBzZXRFeHByLkNvbXBpbGUoKTsKCgkJCXZhciBnZXRFeHByID0gR2V0UHJvZXJ0eUV4cHIoKTsKCQkJdmFyIGdldENvbnRhaW5lciA9IGdldEV4cHIuQ29tcGlsZSgpOwoKCQkJdmFyIHQwID0gbmV3IFRhcmdldENsYXNzMCgpOwoJCQl2YXIgdDEgPSBuZXcgVGFyZ2V0Q2xhc3MxKCk7CgoJCQlDb25zb2xlLldyaXRlTGluZSgidDAncyBWYWx1ZSBpcyAiICsgdDAuVmFsdWUpOwoJCQlDb25zb2xlLldyaXRlTGluZSgidDEncyBWYWx1ZSBpcyAiICsgdDEuVmFsdWUpOwoKCQkJQ29uc29sZS5Xcml0ZUxpbmUoKTsKCQkJQ29uc29sZS5Xcml0ZUxpbmUoKTsKCgkJCXNldENvbnRhaW5lcl8odDAsIDEwMCk7CgkJCUNvbnNvbGUuV3JpdGVMaW5lKCJ0MCdzIFZhbHVlIGlzICIgKyBnZXRDb250YWluZXIodDApKTsKCgkJCXNldENvbnRhaW5lcl8odDEsIDIwMCk7CgkJCUNvbnNvbGUuV3JpdGVMaW5lKCJ0MSdzIFZhbHVlIGlzICIgKyBnZXRDb250YWluZXIodDEpKTsKCgoJCX0KCX0KCgp9Cg==