Expression Tree (İfade Ağacı)

Adından da anlaşılacağı gibi expression tree, ağaç benzeri bir veri yapısında düzenlenmiş expression’lardan başka bir şey değildir. Bir expression tree’deki her düğüm bir ifadedir. Örneğin, x < y matematiksel formülünü temsil etmek için bir ifade ağacı kullanılabilir; burada x, < ve y bir ifade olarak temsil edilecek ve ağaç benzeri yapıda düzenlenecektir.

Expression Tree, bir lambda ifadesinin bellek içi temsilidir. Sorgunun sonucunu değil, sorgunun gerçek öğelerini tutar.

Expression Tree, lambda ifadesinin yapısını şeffaf ve açık hale getirir. Expression tree’deki verilerle, diğer herhangi bir veri yapısında olduğu gibi etkileşim kurabilirsiniz.

Örneğin, aşağıdaki isTeenAgerExpr expression’u göz önünde bulundurun:

Expression<Func<Student, bool>> isTeenAgerExpr = s => s.age > 12 && s.age < 20;

Derleyici yukarıdaki expression’u aşağıdaki expression tree yapısına çevirecektir:

Expression.Lambda<Func<Student, bool>>(
                Expression.AndAlso(
                    Expression.GreaterThan(Expression.Property(pe, "Age"), Expression.Constant(12, typeof(int))),
                    Expression.LessThan(Expression.Property(pe, "Age"), Expression.Constant(20, typeof(int)))),
                        new[] { pe });

Bir expression tree manuel olarak da oluşturabilirsiniz. Aşağıdaki basit lambda ifadesi için bir expression tree’nin nasıl oluşturulacağını görelim:

Func<Student, bool> isAdult = s => s.age >= 18;

Bu Func tipi temsilci, aşağıdaki metot gibi ele alınacaktır:

public bool function(Student s)
{
  return s.Age > 18;
}

İfade ağacını oluşturmak için öncelikle, Student parametrenin türü ve ‘s’nin parametrenin adı olduğu aşağıdaki gibi bir parametre ifadesi oluşturun:

Adım 1: Parameter Expression Oluştur

ParameterExpression pe = Expression.Parameter(typeof(Student), "s");

Şimdi, s’nin parametre ve Age’in Student özellik adı olduğu s.Age ifadesi oluşturmak için Expression.Property()’yi kullanın. (Expression, Expression ağacını manuel olarak oluşturmak için statik yardımcı yöntemler içeren soyut bir sınıftır.)

Adım 2: Property Expression Oluştur

MemberExpression me = Expression.Property(pe, "Age");

Şimdi 18 için sabit bir ifade oluşturun:

Adım 3: Constant Expression Oluştur

ConstantExpression constant = Expression.Constant(18, typeof(int));

Şimdiye kadar s.Age (üye ifadesi) ve 18 (sabit ifade) için ifade ağaçları oluşturduk. Şimdi üye ifadenin sabit ifadeden büyük olup olmadığını kontrol etmemiz gerekiyor. Bunun için Expression.GreaterThanOrEqual() yöntemini kullanın ve üye ifadesini ve sabit ifadeyi parametre olarak iletin:

Adım 4: Binary Expression Oluştur

BinaryExpression body = Expression.GreaterThanOrEqual(me, constant);

Böylece, bir lambda ifade gövdesi s.Yaş >= 18 için bir ifade ağacı oluşturduk. Şimdi parametre ve gövde ifadelerini birleştirmemiz gerekiyor. Lambda ifadesinin gövde ve parametre kısmını birleştirmek için Expression.Lambda(body, parameter dizisi) öğesini kullanın s => s.age >= 18:

Adım 5: Lambda Expression Oluştur

var isAdultExprTree = Expression.Lambda<Func<Student, bool>>(body, new[] { pe });

Bu şekilde, bir lambda ifadesiyle basit Func delegeleri için bir ifade ağacı oluşturabilirsiniz.

Kaynak Kod:

ParameterExpression pe = Expression.Parameter(typeof(Student), "s");

MemberExpression me = Expression.Property(pe, "Age");

ConstantExpression constant = Expression.Constant(18, typeof(int));

BinaryExpression body = Expression.GreaterThanOrEqual(me, constant);

var ExpressionTree = Expression.Lambda<Func<Student, bool>>(body, new[] { pe });

Console.WriteLine("Expression Tree: {0}", ExpressionTree);
		
Console.WriteLine("Expression Tree Body: {0}", ExpressionTree.Body);
		
Console.WriteLine("Number of Parameters in Expression Tree: {0}", 
                                ExpressionTree.Parameters.Count);
		
Console.WriteLine("Parameters in Expression Tree: {0}", ExpressionTree.Parameters[0]);

Sonuç:

Expression Tree: s => (s.Age >= 18)
Expression Tree Body: (s.Age >= 18)
Number of Parameters in Expression Tree: 1
Parameters in Expression Tree: s

Aşağıdaki görüntü, bir ifade ağacı oluşturma sürecinin tamamını göstermektedir: