fork download
  1. using Microsoft.CSharp.RuntimeBinder;
  2. using System;
  3. using System.Dynamic;
  4. using System.Linq.Expressions;
  5.  
  6. namespace ConsoleApplication1
  7. {
  8. public class ExpressionTreeUtils
  9. {
  10. private static Expression<Func<dynamic, decimal>> CreateLambdaCastExpression()
  11. {
  12. // source
  13. var sourceParameterExpression = Expression.Parameter(typeof(object), "source");
  14.  
  15. var binder = Binder.GetMember(
  16. CSharpBinderFlags.None, "IntProp", typeof(ExpressionTreeUtils),
  17. new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
  18.  
  19. // CSharpBinderFlags.ConvertExplicit: explicit cast
  20. // (will convert double to decimal)
  21. // CSharpBinderFlags.None: implicit cast
  22. // (will convert int to decimal)
  23. var convert = Binder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(decimal), typeof(ExpressionTreeUtils));
  24.  
  25. // source.sourceProperty
  26. var sourcePropertyExpression = Expression.Dynamic(
  27. binder, typeof(object), sourceParameterExpression);
  28.  
  29. // (decimal) source;
  30. var castedValueExpression = Expression.Dynamic(
  31. convert, typeof(decimal), sourcePropertyExpression);
  32.  
  33. // () => (decimal) source;
  34. return Expression.Lambda<Func<dynamic, decimal>>(castedValueExpression,
  35. sourceParameterExpression);
  36. }
  37.  
  38. public static void Test()
  39. {
  40. dynamic source = new ExpandoObject();
  41. source.IntProp = 1.5;
  42. decimal r = CreateLambdaCastExpression().Compile()(source);
  43. Console.WriteLine(r);
  44. }
  45. }
  46.  
  47. class Program
  48. {
  49. static void Main(string[] args)
  50. {
  51. ExpressionTreeUtils.Test();
  52. }
  53. }
  54. }
  55.  
Success #stdin #stdout 0.44s 30736KB
stdin
Standard input is empty
stdout
1.5