2012-05-10 7 views
25

Tôi đã sử dụng các biểu thức lambda trong các ngôn ngữ khác trước khi sử dụng chúng trong C#, và vì vậy tôi có thói quen sử dụng _ cho lambdas đơn giản dưới dạng Func<T, TResult>, đặc biệt là cho lambdas đơn giản. (predicates, vv ..). Tuy nhiên, trong C# tôi thường thấy các chữ cái duy nhất được sử dụng thay vì _ cho các loại biểu thức lambda tương tự, chẳng hạn như x,y,z,i,j,k. Cách tiếp cận thư có vẻ kỳ quặc đối với tôi vì những chữ cái đó có một ý nghĩa điển hình khác trong cách sử dụng thông thường, cho các biến vòng lặp. _ thường dễ đọc hơn trong quan điểm của tôi. Là phong cách thư duy nhất thực sự phong cách thành lập cho lambdas trong C#?Kiểu C#: Lambdas, _ => hoặc x =>?

Ví dụ:

những gì tôi đang sử dụng để viết:

var ages = people.Select(_ => _.Age); 

gì tôi nhìn thấy được bằng văn bản thay vì:

var ages = people.Select(x => x.Age); // choice of 'x' is not consistent 
+24

Tôi chưa bao giờ thấy một dấu gạch dưới được sử dụng. –

+0

Cá nhân tôi sử dụng 'w' cho tham số lambda khi nó tầm thường để hiểu tôi đang nói về cái gì. Phần còn lại của http://research.microsoft.com/en-us/um/cambridge/projects/comega/ – Blindy

+1

Đó chỉ là những người yêu say sưa, cá nhân tôi sử dụng tên có ý nghĩa. cả x và _ đều không có ý nghĩa. tuổi tác sẽ là lựa chọn của tôi trong ví dụ của bạn. –

Trả lời

46

Nhiều C# phát triển sử dụng _ để chỉ ra rằng thông số sẽ không được sử dụng và một chữ cái hoặc tên viết tắt khác khi tham số là sử dụng.

nguồn lực khác:

+1

upvote cho bài viết về Charlie Flowers giải thích sự ra đời của việc sử dụng hợp pháp _. –

+1

Ví dụ của tôi không hoàn toàn đúng (tôi nên sử dụng p hoặc người trong các ví dụ đó). Lúc đầu, tôi nghĩ rằng nó chỉ có thể áp dụng cho các trường hợp kiểu _ là generic/unknown, nhưng trong tất cả các trường hợp _ được sử dụng, ít nhất một cái gì đó phải được biết về kiểu trừ khi bạn đang sử dụng các phương thức trên Object (trong trường hợp này bạn muốn sử dụng obj hoặc tương tự), để biện minh đó không bay. Điều này xóa mọi thứ lên một chút. –

+0

không bao giờ được coi là sử dụng '_' cho các tham số không sử dụng. bây giờ tôi có thể sẽ ở khắp mọi nơi .. –

0

Không có 'thành lập' phong cách để đặt tên biến lambda của bạn. Tuy nhiên, dấu gạch dưới thường có nghĩa là một số loại biến thành viên, có nghĩa là kiểu của bạn có thể xung đột với các tiêu chuẩn đặt tên khác so với tên biến thông thường.

Câu chuyện dài ngắn - Làm điều gì phù hợp với bạn.

5

Hoặc bạn có thể sử dụng tên có ý nghĩa, ví dụ:

var ages = people.Select(person => person.Age); 
+0

Bạn là chính xác. Ví dụ của tôi nên đã được sử dụng người. –

22

Đó là tên biến, vì vậy tôi muốn đi với ý tưởng rằng tên sẽ truyền đạt thông tin cần truyền đạt. Thông tin gì _ truyền đạt?

Để cùng một kết thúc, thông tin nào hiện x truyền đạt?

tôi có thể viết ví dụ của bạn như thế này:

var ages = people.Select(p => p.Age); 

Ý tưởng là tôi cảm thấy rằng p ít nhất gợi ý trong bối cảnh của toàn bộ tuyên bố rằng đó là một kỷ lục people. Bạn có thể mang nó hơn nữa:

var ages = people.Select(person => person.Age); 

Bây giờ rằng chuyển tải tới người đọc những gì biến mà thực sự là. Tất nhiên, đối với một tuyên bố nhỏ như vậy, một lập luận có thể được thực hiện rằng nó quá mức cần thiết. Tôi không nghĩ vậy, nhưng đó là vấn đề ưu tiên. (Và không chỉ sở thích của bạn, mà là sở thích của bất kỳ ai phải hỗ trợ mã này.)

Đối với các biểu thức lambda phức tạp hơn, đa dòng, tên càng trở nên quan trọng hơn.Xa hơn nữa là từ ngữ cảnh của biến có nghĩa là gì, tên biến nhiều hơn cần mang theo ngữ cảnh đó.

+6

Tất nhiên, trường hợp loại bỏ tham số (ví dụ, đối với một trình xử lý sự kiện ẩn danh) mà bạn đang viết (_, __) => {notificationEventHandler();} là nơi tôi tiếp tục thấy (và hỗ trợ) việc sử dụng tên chỉ có gạch dưới. –

+1

@TetsujinnoOni: Tất nhiên.Trong trường hợp đó, biến là một biến không. Thông tin duy nhất cần truyền đạt là "Tôi không là gì cả, không sử dụng tôi". – David

+0

Tôi thứ hai sử dụng '_ => _.method()' cho lambdas một dòng, gọi hàm, vì nó làm giảm trọng lượng nhận thức của hướng dẫn. Đặc biệt khi sử dụng Generics, viết 'x => x.method()' chỉ cần thêm rằng việc xem xét phân tách thứ hai của "Cái gì đây 'x'? Nó có phải là một tọa độ trong không gian?". Hãy xem xét các trường hợp sau đây: 'Khởi (_ => _ Init().); ' Được sử dụng với Generics, dấu gạch chân trong trường hợp này hoạt động như một "biểu tượng bypass". Nó tránh sự dư thừa, xác định rằng loại đối số là hiển nhiên và có thể được suy ra từ việc sử dụng - giống như khi sử dụng 'var' để ngăn lặp lại việc khai báo kiểu. – MaDDoX

0

Có một lý do tại sao bạn có thể cho nó một cái tên - bởi vì đôi khi bạn có thể có nhiều đầu vào và cần phải phân biệt chúng:

Func<int,int,int> product = (num1, num2) => (num1 * num2); // takes in two ints, and returns one int 
int x = product(2, 3); 
+0

Đúng, nhưng tôi không nghĩ đó là câu hỏi. –

+0

Sau đó, bạn có thể là một badass thật! (_, __) => (_ * __); EDIT: k, SO tự nhiên lấy dấu gạch dưới của tôi như đánh dấu in nghiêng. Chỉ hiển thị để sử dụng dấu gạch dưới kép (hoặc nhiều hơn) cho nhiều đầu vào. –

+1

@ChrisSinclair, nếu bạn đặt backticks xung quanh biểu thức của bạn những ký tự đặc biệt sẽ được hiển thị như là. –

17

thế nào là một hàm lambda nên khác biệt so với bất kỳ phương pháp nào khác. Nếu ai đó gửi mã với một phương pháp như:

public static int getAge(Person _) 
{ 
    return _.Age; 
} 

hoặc

public static int getAge(Person x) 
{ 
    return x.Age; 
} 

bạn sẽ nói gì?

Theo ý kiến ​​của tôi, hãy chọn tên của tham số cho lambda nên chỉ có ý nghĩa như tham số của bất kỳ phương pháp nào khác. Tôi có thể thỉnh thoảng có ngoại lệ đối với chức năng nhận dạng x => x vì trong trường hợp đó biến không cần phải có ý nghĩa gì, nó thực sự có thể là bất cứ điều gì, nhưng sử dụng dấu gạch dưới hoặc một chữ cái cho mọi thứ trong tâm trí của tôi có thể đọc được. (Vì vậy, nhiều người cho ra những ưu điểm của LINQ/Lambdas là dễ đọc, bị đánh bại nếu bạn làm xáo trộn tất cả các biến.)

+1

Upvote cho sự thay đổi quan điểm tốt – hspain

+0

@ TetsujinnoOni nếu bạn thấy ai đó viết một phương thức 'public int getAge (Person p) {return p.Age;}' bạn sẽ nói gì? Tôi biết nếu tôi thấy ai đó viết rằng tôi muốn nói "bạn nên sử dụng một biến có ý nghĩa hơn và không phải là một chữ viết tắt." Tôi không thấy lý do tại sao cùng một logic không áp dụng như nhau cho một lambda. – Servy

+1

Đối với các vị từ đơn giản, sự tranh chấp là một tên biến có ý nghĩa làm xáo trộn những gì đang xảy ra. Trong cả hai trường hợp mà bạn đã viết, hình thức của định nghĩa phương thức làm tăng lượng nhiễu mà từ đó tín hiệu phải được phân biệt, do đó chi phí đặt tên biến được tăng lên. –

1

Được sử dụng cho biến lớp (thuộc tính) và _ không được sử dụng cho biến cục bộ. Vì vậy, bạn nên sử dụng tên có ý nghĩa cho biến cục bộ và biến lớp.

Ex:

var personList = (from person in people where person.Age > 18 select person).ToList();