2009-10-07 17 views
16

Điều này được lấy cảm hứng từ đồng nghiệp ngôn ngữ-guru của tôi, những người dường như không thể tìm thấy một cách sử dụng tốt cho họ, và sau một vài nỗ lực lame của riêng tôi, tôi phải đồng ý.Whats một trường hợp sử dụng tốt cho .net 4.0 Expression Trees?

Bây giờ tôi biết những khái niệm này có xu hướng chảy dễ dàng hơn nhiều khi bạn nhận được một số lý do thực tiễn tốt.

Hiện tại có vẻ như mục đích duy nhất của nó là cho phép bạn viết nhà cung cấp LINQ?

Có phải không? Có lợi ích nào khác cho điều này không?

+3

http://stackoverflow.com/questions/403088/practical-use-of-expression-trees –

Trả lời

15

Cây biểu hiện rất mạnh mẽ vì chúng cho phép bạn xử lý như dữ liệu. Người dùng quen với việc xây dựng dữ liệu, lưu dữ liệu và quay lại sau.

Cây biểu thức cho phép bạn làm điều tương tự với mã. Ví dụ: bạn có thể lấy dữ liệu nhập của người dùng (các hộp kiểm, phạm vi số, v.v.) và dịch nó thành cây Biểu thức. Cây biểu thức đó sau đó có thể được thực hiện hoặc được lưu trữ để sử dụng sau này. Rất tuyệt.

Hãy suy nghĩ về cách sử dụng thực tế xung quanh báo cáo như xây dựng và lưu các bộ lọc dữ liệu và ánh xạ dữ liệu. Một cách sử dụng thực tế khác là hỗ trợ luồng công việc tùy chỉnh trong ứng dụng của bạn dựa trên các quy tắc do người dùng xác định.

Dưới đây là một chút mã MSDN trên việc sắp xếp các cây biểu thức (http://code.msdn.microsoft.com/exprserialization) để có được ý tưởng chảy.

+0

Cool! Đây là câu trả lời phù hợp với suy nghĩ đặc biệt của tôi. Những ví dụ hay! Tôi thấy bây giờ cách thức này được sử dụng trong các phần khác của khuôn khổ. Vì vậy, sau đó được sử dụng rất nhiều trong WPF? – KevinDeus

+0

Cảm ơn. Vui mừng đã giúp. Tôi đã nghĩ (có thể là quá nhiều) về WPF và các khái niệm lập trình chức năng hữu ích điên rồ như lambdas và các cây biểu đạt sẽ là cốt lõi như thế nào. Vấn đề là WPF được phát hành với .NET 3.0 và LINQ đã được phát hành trong .NET 3.5. Tôi hy vọng các đội WPF/Silverlight sẽ được trang bị lại. XAML sẽ là OK ngoại trừ tất cả các chuỗi darn :). Khởi động Relector và xem họ phải làm gì cho những thứ như System.Windows.DataTrigger. Sự than phiền của họ có thể là một chất xúc tác cho LINQ. –

3

.NET 4.0 Biểu thức cây cũng là cơ sở cho DLR AST của

8

Bạn có thể sử dụng cây biểu thức để chuyển đổi ngôn ngữ miền thành mã thực thi.

1

Tôi đã có trải nghiệm tốt khi họ chuyển ngôn ngữ cụ thể của miền sang AST. Nó cũng khá dễ dàng với bộ điều hợp cây ANTLR để tạo một cây Biểu thức trực tiếp từ ngữ pháp.

4

Giải pháp tìm kiếm sự cố eh?

Cây biểu thức cho phép bạn trình bày mã dưới dạng cấu trúc dữ liệu có thể biến đổi, do đó chúng hoàn hảo để chuyển đổi giữa các ngôn ngữ LINQ to SQL là mạnh nhất hiện nay.

Một cách sử dụng khác ngoài DSL (chuyển đổi) là song song (được chia tách) và ví dụ trong không gian đó là PLINQ.

+0

có một giải pháp tìm kiếm cho một vấn đề như twitter :) – Surya

1

Bạn có thể sử dụng cây biểu thức làm trình tạo mã với mức trừu tượng cao hơn sau đó lắp ráp phát ra và nhanh hơn sau đó là CodeCompiler. Dưới đây là một số bằng chứng về khái niệm mà tôi đã sử dụng để thuyết phục nhóm của chúng tôi sử dụng chúng như một sự thay thế cho CodeCompiler.

[TestClass] 
public class WhenINeedToAccessPropertiesByNameHavingATypeReference 
{ 
    public class SomeCategoryData 
    { 
     public DateTime CreatedDate { get; set; } 
    } 

    [TestMethod] 
    public void ICanDoThatWithAnExpressionAndItPerformsWell() 
    { 
     // INIT 

     var someCategoryData = 
      Enumerable.Range(1970, 100).Select(year => 
       new SomeCategoryData { CreatedDate = new DateTime(year, 1, 1) }).Cast<object>(); 
     var t = typeof(SomeCategoryData); // or it can be: t = someCategoryData.First().GetType(); 
     var compiled = Stopwatch.StartNew(); 

     // ACT 

     var filter = AccessPropertyByNameInCompiledMannerSomehow(t, "CreatedDate"); 

     // ASSERT 

     Trace.WriteLine(string.Format("compiled in: {0}", compiled.Elapsed)); 
     Assert.IsTrue(compiled.ElapsedMilliseconds < 3, "compiles fast enough"); 

     var executed = Stopwatch.StartNew(); 

     // ACT 
     List<object> result = null; 
     for (var i = 0; i < 10000; i++) 
     { 
      result = someCategoryData.Where(d => filter(d, new DateTime(2000, 1, 1), new DateTime(2009, 1, 1))) 
       .ToList(); 
     } 
     executed.Stop(); 
     Trace.WriteLine(string.Format("executed in: {0}", executed.Elapsed)); 

     // ASSERT 
     Assert.AreEqual(10, result.Count, "insure compiled code actually works"); 
     Assert.IsTrue(executed.ElapsedMilliseconds < 300, "runs fast enough"); 
    } 

    private static Func<object, DateTime, DateTime, bool> 
     AccessPropertyByNameInCompiledMannerSomehow(Type t, string fieldToFilterBy) 
    { 
     var objectParameter = Expression.Parameter(typeof(object), "p"); 
     var instance = Expression.Convert(objectParameter, t); 
     var lower = Expression.Parameter(typeof(DateTime), "l"); 
     var upper = Expression.Parameter(typeof(DateTime), "u"); 

     var composite = Expression.Lambda<Func<object, DateTime, DateTime, bool>>(
      Expression.And(
       Expression.LessThanOrEqual(
        lower, 
        Expression.PropertyOrField(instance, fieldToFilterBy) 
        ), 
       Expression.GreaterThanOrEqual(
        upper, 
        Expression.PropertyOrField(instance, fieldToFilterBy) 
        ) 
       ), objectParameter, lower, upper 
      ); 

     return composite.Compile(); 
    } 
} 
2

Câu trả lời nhanh là "không, không chỉ dành cho nhà cung cấp LINQ bây giờ". Đầu tiên, các cây biểu thức được mở rộng bằng thời gian chạy ngôn ngữ động để hỗ trợ các ngôn ngữ động. Về cơ bản, nếu bạn muốn chuyển ngôn ngữ động của riêng bạn sang .NET (như IronPython và IronRuby đã làm), bạn sẽ phải sử dụng các cây biểu thức. OK, không quá nhiều người có ngôn ngữ riêng của họ. Các trường hợp sử dụng khác là gì? Một trong số đó là tạo mã động trong thời gian chạy.Tôi có một ví dụ ở đây: Generating Dynamic Methods with Expression Trees in Visual Studio 2010. Nó giải thích cách bạn có thể sử dụng ET thay vì tạo MSIL để tạo các phương thức động. Trong thực tế, có một số trường hợp sử dụng cho cây biểu thức bên ngoài LINQ ngay cả trong .NET 3.5, nhưng những bài viết đó chưa được viết.

1

Tôi có vài ví dụ here

(xin lỗi về định dạng mã bị hỏng)

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