2008-12-31 57 views
63

Cây biểu đạt là một tính năng tốt đẹp, nhưng sử dụng thực tế của nó là gì? Chúng có thể được sử dụng cho một số loại tạo mã hoặc lập trình meta hay một số kiểu như vậy?Sử dụng thực tế cây biểu thức

+0

bản sao có thể có của [Một số trường hợp trong đó cây biểu thức hữu ích?] (Http://stackoverflow.com/questions/27726/what-are-some-instances-in-which-expression-trees-are- hữu ích) – nawfal

Trả lời

4

Bạn có thể sử dụng chúng để xây dựng nhà cung cấp LINQ của riêng bạn cho một trang web như Google hoặc Flickr hoặc Amazon, trang web của riêng bạn hoặc một nhà cung cấp dữ liệu khác.

20

Marc Gravell đã sử dụng chúng để có hiệu quả tuyệt vời trong MiscUtil để triển khai generic operators.

+11

Darn, đánh bại tôi với nó ;-p –

8

Việc triển khai các nhà cung cấp LINQ chủ yếu được thực hiện bằng cách xử lý các cây biểu thức. Tôi cũng đang sử dụng chúng để loại bỏ các chuỗi chữ từ mã của tôi:

41

Như Jon lưu ý, tôi sử dụng chúng để cung cấp generic operators với .NET 3.5. Tôi cũng sử dụng chúng (một lần nữa trong MiscUtil) để cung cấp truy cập nhanh đến các nhà xây dựng không mặc định (bạn không thể sử dụng Delegate.CreateDelegate với các nhà xây dựng, nhưng Expression hoạt động tốt).

Các ứng dụng khác của cây biểu hiện bằng tay tạo:

Nhưng thực sự, Expression là một cách rất linh hoạt của viết bất kỳ mã năng động. Đơn giản hơn nhiều so với Reflection.Emit và với số tiền của tôi, đơn giản để hiểu hơn CodeDOM. Và trong .NET 4.0, bạn có sẵn even more options. Tôi hiển thị các nguyên tắc cơ bản của mã viết qua Expressionon my blog.

+0

Cảm ơn. blog không hiển thị !!! – pixparker

+0

@pixparker Tôi vừa thử nghiệm nó: làm việc tốt –

12

Tôi sử dụng chúng để tạo truy vấn động, cho dù đó là để sắp xếp hoặc lọc dữ liệu. Như một ví dụ:

IQueryable<Data.Task> query = ctx.DataContext.Tasks; 

if (criteria.ProjectId != Guid.Empty) 
     query = query.Where(row => row.ProjectId == criteria.ProjectId); 

if (criteria.Status != TaskStatus.NotSet) 
     query = query.Where(row => row.Status == (int)criteria.Status); 

if (criteria.DueDate.DateFrom != DateTime.MinValue) 
     query = query.Where(row => row.DueDate >= criteria.DueDate.DateFrom); 

if (criteria.DueDate.DateTo != DateTime.MaxValue) 
    query = query.Where(row => row.DueDate <= criteria.DueDate.DateTo); 

if (criteria.OpenDate.DateFrom != DateTime.MinValue) 
    query = query.Where(row => row.OpenDate >= criteria.OpenDate.DateFrom); 

var data = query.Select(row => TaskInfo.FetchTaskInfo(row)); 
2

Nguyên bởi Jomo Fisher, Gustavo Guerra công bố một phiên bản sửa đổi của các static string dictionary.

Trong đó thông qua cây biểu thức, một biểu thức động cung cấp từ điển thực sự (đọc: ridiculously).

Việc triển khai tạo ra cây quyết định động chọn giá trị corrent theo độ dài của chuỗi đầu vào, sau đó là chữ cái đầu tiên, sau đó là chữ cái thứ hai, v.v.

Điều này cuối cùng chạy nhanh hơn nhiều so với Từ điển tương đương.

13

tôi vừa tạo ra một generic filter function sử dụng ExpressionTree .. Tôi muốn share với các bạn ...

Start

var allFiltered= Filter(AllCustomer, "Name", "Moumit"); 

public static List<T> Filter<T>(this List<T> Filterable, string PropertyName, object ParameterValue) 
{ 
    ConstantExpression c = Expression.Constant(ParameterValue); 
    ParameterExpression p = Expression.Parameter(typeof(T), "xx"); 
    MemberExpression m = Expression.PropertyOrField(p, PropertyName); 
    var Lambda = Expression.Lambda<Func<T, Boolean>>(Expression.Equal(c, m), new[] { p }); 
    Func<T, Boolean> func = Lambda.Compile(); 
    return Filterable.Where(func).ToList(); 
} 

One More

string singlePropertyName=GetPropertyName((Property.Customer p) => p.Name); 

public static string GetPropertyName<T, U>(Expression<Func<T, U>> expression) 
{ 
     MemberExpression body = expression.Body as MemberExpression; 
     // if expression is not a member expression 
     if (body == null) 
     { 
      UnaryExpression ubody = (UnaryExpression)expression.Body; 
      body = ubody.Operand as MemberExpression; 
     } 
     return string.Join(".", body.ToString().Split('.').Skip(1)); 
} 

Make it more expandable

string multiCommaSeparatedPropertyNames=GetMultiplePropertyName<Property.Customer>(c => c.CustomerId, c => c.AuthorizationStatus) 

public static string GetMultiplePropertyName<T>(params Expression<Func<T, object>>[] expressions) 
{ 
     string[] propertyNames = new string[expressions.Count()]; 
     for (int i = 0; i < propertyNames.Length; i++) 
     { 
      propertyNames[i] = GetPropertyName(expressions[i]); 
     } 

     return propertyNames.Join(); 
} 

....... Tôi biết nó cũng có thể được thực hiện bằng Reflection ... nhưng điều này rất nhanh hoặc tôi có thể nói tương đương với Lambda sau lần biên dịch đầu tiên ... Lần lặp đầu tiên chỉ chậm trung bình 10 phần nghìn giây ... Vì vậy, đây là phép thuật Expression Tree. Đơn giản và tuyệt vời .... Tôi nghĩ ... !!!!!!!!

+0

Tốt đẹp! Cảm ơn các ví dụ. –

Các vấn đề liên quan