Upcoming SlideShare
×

# Ciklum net sat12112011-alexander fomin-expressions and all, all, all

2,079 views
2,007 views

Published on

0 Likes
Statistics
Notes
• Full Name
Comment goes here.

Are you sure you want to Yes No
• Be the first to comment

• Be the first to like this

Views
Total views
2,079
On SlideShare
0
From Embeds
0
Number of Embeds
1,402
Actions
Shares
0
3
0
Likes
0
Embeds 0
No embeds

No notes for slide

### Ciklum net sat12112011-alexander fomin-expressions and all, all, all

1. 1. Expressions и все-все-все
3. 3. Expression…остальные trees плюшки Expression Visitor
4. 4. 2+3*42+(3*4)
5. 5. private static void Main(){ Func<int, int, int> f = (x, y) => x + y; Console.WriteLine(f);}System.Func`3[System.Int32,System.Int32,System.Int32][CompilerGenerated]private static int <Main>b__0(int x, int y){ return x+y;}private static void Main(){ var f = new Func<int, int, int>(Program.<Main>b__0)); Console.WriteLine(f); }
6. 6. static void Main(){ Expression<Func<int, int, int>> f = (x, y) => x + y; Console.WriteLine(f);}(x, y) => (x + y)ParameterExpression CS0 = Expression.Parameter(typeof (int), "x");ParameterExpression CS1 = Expression.Parameter(typeof (int), "y");Expression<Func<int, int, int>> f = Expression.Lambda<Func<int, int, int>>( Expression.Add(CS0, CS1), new ParameterExpression[] {CS0, CS1} );
7. 7. Expression<Func<DateTime, int>> f =d => (int) Math.Abs((DateTime.Now - d).TotalSeconds);
8. 8. d => (int) Math.Abs((DateTime.Now - d).TotalSeconds);ParameterExpression CS0 = Expression.Parameter(typeof (DateTime), "d");Expression<Func<DateTime, int>> f = Expression.Lambda<Func<DateTime, int>>( Expression.Convert( Expression.Call( null, (MethodInfo) methodof (Math.Abs), new Expression[] { Expression.Property( Expression.Subtract( Expression.Property(null, (MethodInfo) methodof (DateTime.get_Now)), CS0, (MethodInfo) methodof (DateTime.op_Subtraction) ), (MethodInfo) methodof (TimeSpan.get_TotalSeconds) ) } ), typeof (int) ), new ParameterExpression[] {CS0} );
9. 9. Expression tree
10. 10. d => (int) Math.Abs((DateTime.Now - d).TotalSeconds);
11. 11. .NET 3.0 .NET 4.0• Operators • Blocks• Method calls • Loops• Property getters • Try/Catch/Finally• Collection initializers • Goto/Labels• Object initializers • Variables• Convert/Cast • Assignments• Constants • If/Then/Else (x,y)=>x+y (x,y) => { return x+y; }*
12. 12. ExpressionVisitor
13. 13. protected virtual Expression VisitBinary(BinaryExpression b){ Expression left = this.Visit(b.Left); Expression right = this.Visit(b.Right); return b;}
14. 14. protected virtual Expression VisitBinary(BinaryExpression b){ Expression left = this.Visit(b.Left); Expression right = this.Visit(b.Right); if (left != b.Left || right != b.Right) { return Expression.MakeBinary( b.NodeType, left, right, b.Method ); } return b;}
15. 15. IQueryable<Tree> forest = // ...var queryable = from tree in forest where tree.HasHollow select tree.ColectSomeHoney();var queryable = forest.Where(tree => tree.HasHollow) .Select(tree => tree.ColectSomeHoney());var queryable = Queryable.Select( Queryable.Where(forest, tree => tree.HasHollow), tree => tree.ColectSomeHoney() );var queryable = Enumerable.Select( Enumerable.Where(forest.AsEnumerable (), tree => tree.HasHollow), tree => tree.ColectSomeHoney() );
16. 16. internal override Expression VisitMethodCall(MethodCallExpression m){ Expression instance = base.VisitMethodCall(m); if (m.Method.DeclaringType == typeof(Queryable)) { MethodInfo info = FindEnumerableMethod(m.Method); return Expression.Call(instance, info, source); } return m;}
17. 17. internal override Expression VisitMethodCall(MethodCallExpression m){ Expression instance = base.VisitMethodCall(m); if (m.Method.DeclaringType == typeof(Queryable)) { MethodInfo info = FindEnumerableMethod(m.Method); return Expression.Call(instance, info, source); } return m;}
18. 18. Compiled expressionsstring PasswordPhrase(bool isBear){ return string.Format("{0} очень любит {1}", isBear ? "Мишка" : "Ослик", isBear ? "мёд" : "йод");}
19. 19. ILGenerator generator = //...var label1 = generator.DefineLabel();var label2 = generator.DefineLabel();var label3 = generator.DefineLabel();var label4 = generator.DefineLabel();generator.Emit(OpCodes.Ldstr, "{0} очень любит {1}");generator.Emit(OpCodes.Ldarg_1);generator.Emit(OpCodes.Brtrue_S, label1);generator.Emit(OpCodes.Ldstr, "Мишка");generator.Emit(OpCodes.Br_S, label2);generator.MarkLabel(label1);generator.Emit(OpCodes.Ldstr, ”Ослик");generator.MarkLabel(label2);generator.Emit(OpCodes.Ldarg_1);generator.Emit(OpCodes.Brtrue_S, label3);generator.MarkLabel(label3);generator.Emit(OpCodes.Ldstr, ”мёд");generator.Emit(OpCodes.Br_S, label4);generator.Emit(OpCodes.Ldstr, "йод");generator.MarkLabel(label4);generator.EmitCall(OpCodes.Call, typeof(String).GetMethod("Format"), new[] { typeof(string), typeof(ob ject), typeof(object) });generator.Emit(OpCodes.Ret);
20. 20. Func<bool, string> Emit(){ var isBear = Expression.Parameter(typeof (bool), "isBear"); var lambda = Expression.Lambda<Func<bool, string>>( Expression.Call( Method(() => string.Format("", null, null)), Expression.Constant("{0} очень любит {1}"), Expression.Condition(isBear, Expression.Constant("Мишка"), Expression.Constant("Ослик")), Expression.Condition(isBear, Expression.Constant("мёд"), Expression.Constant("йод") ) ) ); Func<bool, string> func = lambda.Compile(); return func;}
21. 21. Reflection in compile timepublic class Tree{ public Honey ColectSomeHoney() { //... return new Honey(); }}private static void Main(){ MethodInfo method = typeof(Tree).GetMethod( "ColectSomeHoney", BindingFlags.Public | BindingFlags.Instance );}
22. 22. Reflection in compile timepublic class Tree{ public Honey CollectSomeHoney() { //... return new Honey(); }}private static void Main(){ MethodInfo method = typeof(Tree).GetMethod( "ColectSomeHoney", BindingFlags.Public | BindingFlags.Instance );}
23. 23. Reflection in compile timepublic class Tree{ public Honey CollectSomeHoney() { //... return new Honey(); }}private static void Main(){ MethodInfo method = typeof(Tree).GetMethod( "ColectSomeHoney", BindingFlags.Public | BindingFlags.Instance );}
24. 24. Reflection in compile timeprivate static void Main(){ var method = GetMethod<Tree>(x => x.ColectSomeHoney());}public static MethodInfo GetMethod<T>(Expression<Action<T>> e){ return ((MethodCallExpression) e.Body) .Method;}
25. 25. Reflection in compile timeprivate static void Main(){ var method = GetMethod<Tree>(x => x.CollectSomeHoney());}public static MethodInfo GetMethod<T>(Expression<Action<T>> e){ return ((MethodCallExpression) e.Body) .Method;}
26. 26. IQueryableinterface IQueryable<T> : IEnumerable<T> , IQueryable{ Type ElementType { get; } Expression Expression { get; } IQueryProvider Provider { get; }}interface IQueryProvider{ IQueryable CreateQuery(Expression e) ; IQueryable<T> CreateQuery<T> (Expression e); object Execute (Expression expression); object Execute (Expression expression);}
27. 27. IQueryable
28. 28. Expressions в C# — impress yourself! http://habrahabr.ru/blogs/net/83169/
29. 29. LINQ: Building an IQueryable provider series http://blogs.msdn.com/b/mattwar/archive/2008/11/18/linq-links.aspx
30. 30. Винни-Пух и Все-Все-все ISBN: 978-5-17-064151-2