2009-11-29 41 views
7

Không được phép có toán tử điều kiện trong biểu thức lambda trong ForEach?Sử dụng toán tử điều kiện trong biểu thức lambda trong ForEach() trên Danh sách chung?

List<string> items = new List<string>{"Item 1", "Item 2", "Item I Care About"}; 

string whatICareAbout = ""; 

// doesn't compile :(
items.ForEach(item => item.Contains("I Care About") ? 
whatICareAbout += item + "," : whatICareAbout += ""); 

Compilation lỗi -> "Chỉ chuyển nhượng, gọi điện thoại, tăng, sụt lần, và biểu tượng mới có thể được sử dụng như một tuyên bố"

Cố gắng sử dụng một bình thường nếu không làm việc, hoặc:

// :(
items.ForEach(item => if (item.Contains("I Care About")) {whatICareAbout += item + ", ";} 

Chỉ cần không thể?

+2

Sheesh Tôi đặc biệt ấn tượng với câu trả lời, tất cả chỉ trong vài phút hỏi :) Tôi nghĩ @SLaks trả lời ý định của câu hỏi của tôi, nhưng Tổng hợp() thổi tâm trí của tôi! :) Cảm ơn một lần nữa tất cả mọi người :) – Jamezor

+1

Bạn đã có một biểu thức chuỗi như là một loại toán tử có điều kiện, và bạn cần một câu lệnh cho phương thức .ForEach() của bạn. Đó là lý do tại sao có lỗi biên dịch. –

+1

@Roman - Tôi hiểu ngay bây giờ! Tôi nghĩ về một? x: y là viết tắt của if (a) {x} else {y} nhưng? trả về giá trị của x và y, mà là một chuỗi trong trường hợp này ... – Jamezor

Trả lời

26

Bạn đang sử dụng biểu thức lambda ngắn hơn, chỉ cho phép một biểu thức.
Bạn cần có dạng dài, cho phép nhiều câu lệnh.

Ví dụ:

items.ForEach(item => { 
    if (item.Contains("I Care About")) 
     whatICareAbout += item + ", "; 
}); 
1

Hãy thử ngoặc:

items.ForEach(item => item.Contains("I Care About") ? (whatICareAbout += item + ",") : (whatICareAbout += "")); 

+ = có độ ưu tiên cao hơn, đó có thể là lý do tại sao bạn đang nhận lỗi?. Với dấu ngoặc đơn, lỗi có thể biến mất. Không chắc chắn 100% về điều này, mặc dù ... các biểu thức lambda có thể có các hạn chế bổ sung ngăn chặn việc sử dụng các câu lệnh gán.

UPDATE:

Thay vì nhiều + = câu lệnh, nó sạch hơn rất nhiều để đưa các điều kiện ở phía bên tay phải của nhiệm vụ, như thế này:

List<string> items = new List<string> { "one", "two", "three" }; 
string whatICareAbout = ""; 
items.ForEach(item => whatICareAbout += item.Contains("I Care About") ? (item + ",") : ""); 

UPDATE 2:

Nhưng sẽ tốt hơn nếu chỉ sử dụng Aggregate() vì nó được thiết kế cho chính xác kịch bản này. Dưới đây là một mẫu:

string whatICareAbout = items.Aggregate("", (total, item) => item.Contains("I Care About") ? (total + item + ",") : total); 

Nhưng tôi nghĩ @Matt Breckon's câu trả lời ở trên (mà tôi chỉ thấy như tôi sắp sửa đăng bài này) thậm chí còn tốt hơn so với ví dụ của tôi vì nó giao dịch với loại bỏ các thiết bị đầu cuối "". Nhìn vào câu trả lời của anh ấy ... :-)

5

Bạn đang cố gắng đạt được điều gì? Bạn đang cố gắng tạo thành một chuỗi các mục được phân tách bằng dấu phẩy mà chúng chứa một giá trị cụ thể? Trong LINQ bạn sẽ đạt được điều này bằng cách sử dụng các mục sau:

List<string> items = new List<string> { "Item 1", "Item 2", "Item I Care About", "Item I Care About", "Item I Care About" }; 
string whatICareAbout = items.Where(x => x.Contains("I Care About")) 
           .Aggregate((y, z) => y + ", " + z); 

Kết quả đầu ra của mục này là "Mục tôi quan tâm, mục tôi quan tâm, mục tôi quan tâm".

Lưu ý: tổng hợp là một cách tuyệt vời để bảo đảm không có dấu ""

+0

Sử dụng 'Tổng hợp' cho sting concat là một ý tưởng rất gọn gàng mà tôi đã không nghĩ đến. Bạn có thể dễ dàng thay đổi nó để sử dụng một 'StringBuilder' vì' StringBuilder' có một giao diện thông thạo. – SLaks

+0

hah, tôi vừa thêm một mẫu mã tổng hợp() vào câu trả lời ban đầu của tôi ... nhưng tôi thích của bạn tốt hơn. +1! –

4

Vấn đề là biểu hiện

item.Contains("I Care About") ? whatICareAbout += item + "," : whatICareAbout += "" 

không phải là một tuyên bố. Nó chỉ trả về một giá trị có loại string.

Có một trick để làm cho nó làm việc (chỉ để cho vui):

items.ForEach(item => (item.Contains("I Care About") ? 
    whatICareAbout += item + "," : whatICareAbout += "").GetType()); 

tôi chỉ cần thêm cuộc gọi đến .GetType() phương pháp để tạo ra một tuyên bố từ biểu hiện ban đầu, và nó được biên dịch.

+0

Và đối với '.ForEach()' bạn cần một câu lệnh :) –

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