2008-09-12 24 views
40

Tôi đang sử dụng C#.Làm cách nào để bạn khai báo nội dòng của đại biểu được ủy quyền?

Vì vậy, tôi có một đối tượng có một số trường, không quan trọng gì. Tôi có một danh sách chung của các đối tượng này.

List<MyObject> myObjects = new List<MyObject>(); 
myObjects.Add(myObject1); 
myObjects.Add(myObject2); 
myObjects.Add(myObject3); 

Vì vậy, tôi muốn xóa đối tượng khỏi danh sách của mình dựa trên một số tiêu chí. Ví dụ: myObject.X >= 10. Tôi muốn sử dụng phương thức RemoveAll(Predicate<T> match) để thực hiện việc này. Tôi biết tôi có thể xác định một đại biểu có thể được chuyển vào RemoveAll, nhưng tôi muốn biết cách xác định nội tuyến này với một đại biểu ẩn danh, thay vì tạo một loạt các hàm đại biểu chỉ được sử dụng ở một nơi.

Trả lời

52

Có hai lựa chọn, một đại biểu rõ ràng hoặc một delegate cải trang thành một cấu trúc lamba:

rõ ràng đại biểu

myObjects.RemoveAll(delegate (MyObject m) { return m.X >= 10; }); 

lambda

myObjects.RemoveAll(m => m.X >= 10); 

Addition:

Hiệu suất khôn ngoan cả hai đều bình đẳng. Như một vấn đề của thực tế, cả hai cấu trúc ngôn ngữ tạo ra cùng một IL khi biên dịch. Điều này là do C# 3.0 về cơ bản là một phần mở rộng trên C# 2.0, vì vậy nó biên dịch C# 2.0 cấu trúc :)

15

Lambda C# 3.0 cách:

myObjects.RemoveAll(m => m.x >= 10); 

Các nặc danh đại biểu C# 2.0 cách:

myObjects.RemoveAll(delegate (MyObject m) { 
    return m.x >= 10; 
}); 

Và, đối với những kẻ VB, lambda cách VB 9.0:

myObjects.RemoveAll(Function(m) m.x >= 10) 

Thật không may, VB không hỗ trợ một đại biểu ẩn danh.

+0

Tại sao VB nên muốn đại biểu vô danh khi nó có lambdas? Và có, phiên bản tiếp theo sẽ có nhiều dòng lambdas và lambdas không trả về một giá trị (= 'Sub' s). –

+2

Vì những lý do bạn vừa nêu - các câu lệnh nhiều dòng và các hàm không trả về một giá trị. Tốt để biết nó sẽ có trong phiên bản tiếp theo, nhưng C# đã có nó từ năm 2005. –

10
//C# 2.0 
    RemoveAll(delegate(Foo o){ return o.X >= 10; }); 

hoặc

//C# 3.0 
    RemoveAll(o => o.X >= 10); 

hoặc

Predicate<Foo> matches = delegate(Foo o){ return o.X >= 10; }); 
    //or Predicate<Foo> matches = o => o.X >= 10; 
    RemoveAll(matches); 
0

Predicate là một đại biểu mà phải mất một param và trả về một boolean.

Chúng ta có thể làm như vậy trong những cách sau đây

1) Sử dụng inline biểu Lambda

RemoveAll(p=> p.x > 2); 

2) Sử dụng chức năng ẩn danh

RemoveAll(delegate(myObject obj){ 

    return obj.x >=10; 
}) 

3) Sử dụng Predicate ủy quyền

Predicate<myObject> matches = new Predicate<myObject>(IsEmployeeIsValid); 
RemoveAll(matches); 

Predicate<Foo> matches = delegate(Foo o){ return o.X >= 20; }); 
RemoveAll(matches); 

3) Khai báo một đại biểu rõ ràng mới và trỏ đến một hàm

public delegate bool IsInValidEmployee (Employee emp); 

IsInValidEmployee invalidEmployeeDelegate = new IsInValidEmployee(IsEmployeeInValid); 
myObjects.RemoveAll(myObject=>invalidEmployeeDelegate(myObject); 

// chức năng thực tế

public static bool IsEmployeeInValid(Employee emp) 
{ 
    if (emp.Id > 0) 
     return true; 
    else 
     return false; 
} 
Các vấn đề liên quan