2011-12-07 54 views
8

Từ C# trong chiều sâu:Chuyển đổi biểu thức lambda vào một cây biểu

Không phải tất cả các biểu thức lambda có thể được chuyển đổi sang cây biểu thức. Bạn không thể chuyển đổi lambda bằng một khối câu lệnh (thậm chí chỉ một câu lệnh trả về là ) thành một cây xuất hiện -> nó phải ở dạng chỉ đánh giá một biểu thức.

Kể từ khi tuyên bố LINQ-to-Object không được chuyển đổi thành các đối tượng cây biểu thức, các từ ngữ lambda sử dụng với các nhà khai thác LINQ-to-Object có thể chứa một khối lệnh

 string[] count = { "one ", "two ", "three ", "four ", "five ", "six " }; 
     IEnumerable<int> result = count.Select(item => 
           { 
            Console.WriteLine(item); 
            return item.Length; 
           }); 
     foreach (int i in result); 

OUTPUT:

one two three four five six 

tôi vẫn chưa bắt đầu học LINQ-to-SQL hoặc LINQ-To-Đối tượng, nhưng tôi giả định biểu thức lambda sử dụng với lệnh LINQ hoạt động trên IQueryable<T> chỉ có thể từng chứa một biểu thức đơn , do sự phục hồi mà chỉ có một biểu thức duy nhất có thể được chuyển đổi thành một cây biểu thức?

Cảm ơn bạn

Trả lời

14

Nó không chỉ rằng họ chỉ có thể chứa một biểu thức duy nhất - đó là không thể là một tuyên bố lambda ở tất cả. Ngay cả một khối như thế này:

var result = query.Select(item => { return item.Length; }); 

sẽ không hợp lệ cho LINQ to SQL. Nó sẽ phải được thể hiện dưới dạng:.

var result = query.Select(item => item.Length); 

(Tôi vừa mới nhận thấy rằng đó là các bit của cuốn sách bạn trích dẫn Oh tốt - nó cho thấy tôi phù hợp :)

Lưu ý rằng tính .NET 4, các cây biểu hiện tự do có khả năng chứa các khối, nhưng trình biên dịch C# không thể dịch các câu lệnh lambdas thành loại cây biểu thức đó. Có những hạn chế khác nữa, nhưng chúng hiếm khi gây ra vấn đề.

này được quy định tại phần 4.6 của C# 4 spec:

Không phải tất cả các chức năng ẩn danh có thể được biểu diễn dưới dạng cây biểu thức. Ví dụ, các hàm ẩn danh với các phần tử câu lệnh và các hàm ẩn danh có chứa các biểu thức gán không thể được biểu diễn. Trong những trường hợp này, chuyển đổi vẫn tồn tại, nhưng sẽ không thành công trong thời gian biên dịch.

+5

Bây giờ, những gì trên trái đất sẽ * bạn * biết về một cái gì đó được đề cập trong ** C# trong chiều sâu **? Đưng bận tâm. –

+0

cảm ơn cả hai rất nhiều – AspOnMyNet

+0

@Jon: Nó đột nhiên xảy ra với tôi làm thế nào rất liên quan đến câu hỏi này là ở đó tại http://stackoverflow.com/questions/8405423/do-at-compile-time-linq-to-objects- statement-also-get-dịch-into-expressio * nháy mắt nháy mắt * – AspOnMyNet

1

Bạn chính xác, chúng chỉ có thể chứa một biểu thức duy nhất.

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