2010-02-05 18 views
8

Tôi muốn một phương pháp mà có API sau:Phương pháp C# chấp nhận một vị từ - điều này có ổn không?

//get all users with a role of admin 
var users = myRepository.GetUsers(u => u.Role == Role.Admin); 

Will cái gì đó như công việc này?

IList<User> GetUsers(Func<User, bool> predicate) 
{    
    var users = GetAllUsers(); 
    return users.Where(predicate).ToList();               
} 

Nếu vậy, tôi wil có thể xác định vị phức tạp hơn như (giả):

myRepository.GetUsers(u => u.CreatedDate is upto 14 days old); 
+1

Tại sao bạn không muốn trả lại người dùng IEnumerable? –

+0

Là một IEnumerable thích hợp hơn vì nó linh hoạt hơn? – Ben

+1

Một IList là một IEnumerable, do đó, một IEnumerable là có được ít linh hoạt. Tôi nghĩ rằng các bình luận có thể đã được hướng đến các cuộc gọi không cần thiết có thể để ToList()? –

Trả lời

19

Điều đó có vẻ hoàn toàn ổn. Tuy nhiên, nếu bạn muốn sử dụng vị với một cái gì đó giống như LINQ to SQL, bạn muốn sử dụng:

IList<User> GetUsers(Expression<Func<User, bool>> predicate) 

Điều đó có nghĩa các biểu thức lambda sẽ được chuyển đổi thành một cây biểu hiện thay vì một đại biểu - và biểu thức cây sau đó có thể được chuyển đổi thành SQL.

+0

Thực sự đánh giá cao phản hồi của bạn. Cảm ơn – Ben

+2

+1 Giải thích đó đã làm sáng tỏ sự hiểu biết của tôi về LINQ bằng một vài phần trăm. Nhiều nghĩa vụ. :) –

+0

Cảm ơn bạn rất nhiều vì câu trả lời này. Tôi đang sử dụng LINQ to SQL, và chỉ sử dụng Func ném ngoại lệ OutOfMemory. Điều này làm việc hoàn hảo. – AngieM

3

Vâng, điều này sẽ làm việc.

Điều bạn đang nói với trình biên dịch là bạn sẽ chuyển một hàm hoạt động trên đối tượng User và trả về một bool - chức năng trông như thế nào là hoàn toàn tùy thuộc vào bạn. Bạn có thể nhận được các công cụ làm tổ khá phức tạp bằng cách sử dụng ors (||) và ands (&&), nhưng nếu nó quá khó để xem những gì vị ngữ đang làm, bạn có lẽ nên xem xét tái cấu trúc.

Nhưng về cơ bản bất kỳ lambda nào lấy ví dụ u làm đối tượng User và biến thành biểu thức trả về bool sẽ hoạt động.

2

Một tip: bạn có thể sử dụng Predicate <T> thay vì Func < T, bool >, đó là rõ ràng hơn một chút (Predicate <T> được tích hợp sẵn trong Net 3.5, hệ thống không gian tên).

+2

'Predicate ' thực sự là trong .NET 2.0, nhưng 'Func ' có xu hướng được sử dụng trong LINQ - một phần vì một số phương thức có 'Func '. –

+0

Ah Tôi quên rằng đó là trong 2.0; bạn có thể cho tôi một vài ví dụ về các phương thức sử dụng Func không? Cảm ơn – ljs

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