2009-07-07 34 views
166

Sử dụng các tính năng hiểu trình biên dịch C# truy vấn, bạn có thể viết mã như:Mã tương đương với 'let' từ khóa trong phương pháp khuyến nông LINQ xích gọi

var names = new string[] { "Dog", "Cat", "Giraffe", "Monkey", "Tortoise" }; 
var result = 
    from animalName in names 
    let nameLength = animalName.Length 
    where nameLength > 3 
    orderby nameLength 
    select animalName; 

Trong biểu thức truy vấn trên, các từ khóa let cho phép một giá trị được chuyển tiếp tới các hoạt động ở vị trí và đơn đặt hàng mà không có các cuộc gọi trùng lặp tới animalName.Length.

Bộ tương đương của các cuộc gọi phương thức mở rộng LINQ đạt được những gì từ khóa "cho" ở đây?

+11

FYI, đặc điểm kỹ thuật C# 3.0 giải thích mọi quy tắc dịch đọc hiểu trong chi tiết đầy đủ. –

+16

và đối với những người tìm thấy spec nặng đi, C# trong Depth của Jon Skeet cũng bao gồm nó ;-p –

+4

Tôi thích nó khi tôi tất cả như "tự hỏi làm thế nào' từ khóa 'bản đồ để mở rộng phương pháp ... Tôi sẽ google nó nhưng tôi nghi ngờ tìm kiếm của tôi sẽ tìm thấy bất cứ điều gì nhưng rác ... SO FTW! " – Will

Trả lời

212

Không có hoạt động riêng; nó quay lưng lại với số Select. Bạn có thể thấy điều này nếu bạn sử dụng "phản xạ" để kéo ra một dll hiện có.

nó sẽ là một cái gì đó như:

var result = names 
     .Select(animalName => new { nameLength = animalName.Length, animalName}) 
     .Where(x=>x.nameLength > 3) 
     .OrderBy(x=>x.nameLength) 
     .Select(x=>x.animalName); 
+2

Woah, tôi không biết bạn có thể tự động đóng gói bằng cách sử dụng toán tử mới như thế. –

+17

Bạn cũng có thể sử dụng nút "lambda" nhỏ trong ngăn kết quả của LinqPad để xem mã được tạo * nếu * bạn bắt đầu bằng Queryable.Nói cách khác, nếu bạn thay đổi dòng đầu tiên thành var names = new string [] {"Dog", ...} .AsQueryable(); sau đó chạy toàn bộ điều trong LinqPad, nhấp vào nút lambda nhỏ, bạn sẽ thấy mã được tạo ra hầu như giống hệt với câu trả lời của Marc. –

+1

Tôi cần sử dụng phương thức mở rộng '.Dump()' trong LinqPad để xem lambda kết quả. – justanotherdev

77

Có một bài viết tốt here

Về cơ bản let tạo ra một tuple nặc danh. Số tiền này tương đương với:

var result = names.Select(
    animal => new { animal = animal, nameLength = animal.Length }) 
.Where(x => x.nameLength > 3) 
.OrderBy(y => y.nameLength) 
.Select(z => z.animal); 
+3

Dường như blog đã biến mất –

+2

Không còn nữa, hiện đang liên kết tới lưu trữ web. – Ziv

+0

Tôi trích dẫn bài viết ở trên 'có vẻ thận trọng để khuyên bạn không nên sử dụng từ khóa let trong trường hợp bạn không cần phải biến đổi một biến ' –

5

Ngoài ra còn có một phương pháp khuyến nông .Let trong System.Interactive, nhưng mục đích của nó là để giới thiệu một biểu thức lambda được đánh giá 'in-line' trong một biểu hiện thông thạo. Ví dụ, hãy xem xét (trong LinqPad, nói) các biểu thức sau đây tạo ra số ngẫu nhiên mới mỗi khi nó được thực hiện:

var seq = EnumerableEx.Generate(
    new Random(), 
    _ => true, 
    _ => _, 
    x => x.Next()); 

Để thấy rằng mẫu ngẫu nhiên mới xuất hiện mỗi lần, hãy xem xét những điều sau

seq.Zip(seq, Tuple.Create).Take(3).Dump(); 

trong đó tạo ra các cặp trong đó bên trái và bên phải là khác nhau. Để sản xuất cặp, trong đó bên trái và bên phải là luôn luôn giống nhau, làm điều gì đó như sau:

seq.Take(3).ToList().Let(xs => xs.Zip(xs, Tuple.Create)).Dump(); 

Nếu chúng ta có thể gọi biểu thức lambda trực tiếp, chúng ta có thể viết

(xs => xs.Zip(xs, Tuple.Create))(seq.Take(3).ToList()).Dump(); 

Nhưng chúng ta không thể gọi các biểu thức lambda như thể chúng là các phương thức.

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