fork download
  1. using System;
  2. using System.Linq.Expressions;
  3. using System.Runtime.CompilerServices;
  4. using Microsoft.CSharp.RuntimeBinder;
  5.  
  6. namespace ConsoleApplication1
  7. {
  8. class TargetClass0
  9. {
  10. private void Call(int arg)
  11. {
  12. //実際呼び出されたか確認するため
  13. Console.WriteLine("TargetClass0 is Called value:" + arg.ToString());
  14. }
  15.  
  16. public int Value
  17. {
  18. get;
  19. set;
  20. }
  21. }
  22.  
  23. class TargetClass1
  24. {
  25. public int Value;
  26.  
  27. public void Call(int arg)
  28. {
  29. //実際呼び出されたか確認するため
  30. Console.WriteLine("TargetClass1 is Called value:" + arg.ToString());
  31. }
  32.  
  33. }
  34.  
  35. class Program
  36. {
  37. static void SetProperty(dynamic d,int value)
  38. {
  39. d.Value = value;
  40. }
  41.  
  42. static void InvokeDelegate(dynamic d, int value)
  43. {
  44. d(value);
  45. }
  46.  
  47.  
  48. static Expression<Action<object, int>> SetPropertyExpr()
  49. {
  50. var binder = Binder.SetMember(CSharpBinderFlags.ResultDiscarded, "Value", typeof(Program)
  51. , new[]{CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None,"target"),
  52. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType,"arg")});
  53.  
  54. var targetExpr = Expression.Parameter(typeof(object), "target");
  55. var paramExpr=Expression.Parameter(typeof(int),"arg");
  56.  
  57. var dynamicExpr = Expression.MakeDynamic(typeof(Action<CallSite, object, int>), binder, targetExpr, paramExpr);
  58.  
  59. return Expression.Lambda<Action<object, int>>(dynamicExpr,targetExpr, paramExpr);
  60.  
  61. }
  62.  
  63. static Expression<Func<object, int>> GetProertyExpr()
  64. {
  65. var getBinder = Binder.GetMember(CSharpBinderFlags.None, "Value", typeof(Program),
  66. new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, "Target") });
  67.  
  68. var convBinder = Binder.Convert(CSharpBinderFlags.None, typeof(int), typeof(Program));
  69.  
  70. var targetExpr = Expression.Parameter(typeof(object), "target");
  71.  
  72. var getExpr = Expression.Dynamic(getBinder, typeof(object), targetExpr);
  73. var convExpr = Expression.Dynamic(convBinder, typeof(int), getExpr);
  74.  
  75. return Expression.Lambda<Func<object, int>>(convExpr, targetExpr);
  76. }
  77.  
  78.  
  79. static void Main(string[] args)
  80. {
  81.  
  82.  
  83. var setExpr = SetPropertyExpr();
  84. var setContainer_ = setExpr.Compile();
  85.  
  86. var getExpr = GetProertyExpr();
  87. var getContainer = getExpr.Compile();
  88.  
  89. var t0 = new TargetClass0();
  90. var t1 = new TargetClass1();
  91.  
  92. Console.WriteLine("t0's Value is " + t0.Value);
  93. Console.WriteLine("t1's Value is " + t1.Value);
  94.  
  95. Console.WriteLine();
  96. Console.WriteLine();
  97.  
  98. setContainer_(t0, 100);
  99. Console.WriteLine("t0's Value is " + getContainer(t0));
  100.  
  101. setContainer_(t1, 200);
  102. Console.WriteLine("t1's Value is " + getContainer(t1));
  103.  
  104.  
  105. }
  106. }
  107.  
  108.  
  109. }
  110.  
Success #stdin #stdout 0.31s 35568KB
stdin
Standard input is empty
stdout
t0's Value is 0
t1's Value is 0


t0's Value is 100
t1's Value is 200