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

41
Expressions и все-все- все

Transcript of Ciklum net sat12112011-alexander fomin-expressions and all, all, all

Page 1: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

Expressions и все-все-все

Page 2: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

http://crew.taucraft.com/

http://sane.habrahabr.ru

http://der-waldgeist.blogspot.com

http://twitter.com/AlexSane

http://www.google.com/profiles/shurickFomin

Page 3: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

Expression trees…остальные

плюшки

Expression Visitor

Page 4: Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Page 5: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

2+3*4

2+(3*4)

Page 6: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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); }

Page 7: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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}

);

Page 8: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

Expression<Func<DateTime, int>> f = d => (int) Math.Abs((DateTime.Now - d).TotalSeconds);

Page 9: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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} );

d => (int) Math.Abs((DateTime.Now - d).TotalSeconds);

Page 10: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

Expression tree

Page 11: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

d => (int) Math.Abs((DateTime.Now - d).TotalSeconds);

Page 12: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

.NET 3.0

• Operators• Method calls• Property getters• Collection initializers• Object initializers• Convert/Cast• Constants

(x,y)=>x+y

.NET 4.0

• Blocks• Loops• Try/Catch/Finally• Goto/Labels• Variables• Assignments• If/Then/Else

(x,y) => { return x+y; }*

Page 13: Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Page 14: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

ExpressionVisitor

Page 15: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

protected virtual Expression VisitBinary(BinaryExpression b) {

Expression left = this.Visit(b.Left); Expression right = this.Visit(b.Right); return b;

}

Page 16: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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;

}

Page 17: Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Page 18: Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Page 19: Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Page 20: Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Page 21: Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Page 22: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

IQueryable<Tree> forest = // ...var queryable = from tree in forest

where tree.HasHollowselect 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() );

Page 23: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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;

}

Page 24: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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;

}

Page 25: Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Page 26: Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Page 27: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

Compiled expressions

string PasswordPhrase(bool isBear) {

return string.Format("{0} очень любит {1}", isBear ? "Мишка" : "Ослик",

isBear ? "мёд" : "йод"); }

Page 28: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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(object),

typeof(object) });generator.Emit(OpCodes.Ret);

Page 29: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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;

}

Page 30: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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);

}

Page 31: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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);

}

Page 32: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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);

}

Page 33: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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;

}

Page 34: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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;

}

Page 35: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

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);

}

Page 36: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

IQueryable

Page 37: Ciklum net sat12112011-alexander fomin-expressions and all, all, all
Page 38: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

Expressions в C# — impress yourself!

http://habrahabr.ru/blogs/net/83169/

Page 39: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

LINQ: Building an IQueryable provider series

http://blogs.msdn.com/b/mattwar/archive/2008/11/18/linq-links.aspx

Page 40: Ciklum net sat12112011-alexander fomin-expressions and all, all, all

Винни-Пух и Все-Все-все

ISBN: 978-5-17-064151-2

Page 41: Ciklum net sat12112011-alexander fomin-expressions and all, all, all