Sử dụng quá nhiều phương pháp mở rộng không tốt vì cùng một lý do sử dụng quá nhiều toán tử quá tải là xấu. Hãy để tôi giải thích.
Hãy xem ví dụ về quá tải toán tử trước. Khi bạn nhìn thấy mã:
var result = myFoo + myBar;
bạn muốn hy vọng rằng myFoo
và myBar
nhiều loại số, và operator +
là thực hiện bổ sung. Điều này là hợp lý, trực quan, dễ hiểu. Nhưng một khi nhà điều hành quá tải vào hình ảnh, bạn không còn có thể chắc chắn về những gì myFoo + myBar
thực sự đang làm - toán tử + có thể bị quá tải thành có nghĩa là bất cứ điều gì. Bạn không thể chỉ đọc mã và tìm ra những gì đang xảy ra mà không cần phải đọc tất cả các mã nằm bên dưới các kiểu liên quan đến biểu thức. Hiện tại, operator +
đã bị quá tải đối với các loại như String
hoặc DateTime
- tuy nhiên, có một cách diễn giải trực quan về những gì bổ sung có nghĩa là trong những trường hợp đó. Quan trọng hơn, trong những trường hợp thông thường, nó bổ sung thêm rất nhiều sức mạnh biểu cảm cho mã. Vì vậy, nó có giá trị tiềm năng nhầm lẫn.
Vì vậy, tất cả điều này phải làm gì với các phương pháp mở rộng? Vâng, các phương pháp mở rộng giới thiệu một tình huống tương tự.Nếu không có phương pháp khuyến nông, khi bạn nhìn thấy:
var result = myFoo.DoSomething();
bạn có thể giả định rằng DoSomething()
hoặc là một phương pháp myFoo
hoặc một trong đó là các lớp cơ sở. Điều này rất đơn giản, dễ hiểu và trực quan. Nhưng với các phương pháp mở rộng, DoSomething()
có thể được định nghĩa ở bất kỳ đâu - và tệ hơn, định nghĩa phụ thuộc vào tập hợp các câu lệnh using
trong tệp mã và đưa nhiều lớp vào hỗn hợp, bất kỳ nhóm nào có thể lưu trữ triển khai DoSomething()
.
Bây giờ đừng hiểu lầm tôi. Cả hai phương thức quá tải và mở rộng của toán tử là các tính năng ngôn ngữ hữu ích và mạnh mẽ. Nhưng hãy nhớ - với sức mạnh to lớn có trách nhiệm lớn. Bạn nên sử dụng các tính năng này khi chúng cải thiện độ rõ ràng hoặc khả năng thực hiện. Nếu bạn bắt đầu sử dụng chúng một cách bừa bãi, chúng sẽ thêm sự nhầm lẫn, phức tạp và có thể là khuyết điểm đối với những gì bạn đang cố gắng tạo ra.
Trớ trêu thay vì đây là, phương pháp mở rộng đó có thể được đặt ngay bên cạnh phương thức '.ForEach' của tôi! Tôi thấy rằng dễ hiểu và ít chi tiết hơn so với vòng lặp for, nó cũng sẽ làm cho nó không thể vô tình giới thiệu off bằng 1 lỗi bằng cách sử dụng i
@Chris: Trong trường hợp đó, chỉ cần sử dụng foreach. Bài đăng tuyệt vời của Eric ở đây giải thích các vấn đề với việc thực hiện ForEach - http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx –
Và chưa, F # bao gồm 'Seq.iter' tương đương với phương thức mở rộng 'IEnumerable .ForEach'. Tôi biết, ngôn ngữ khác nhau, triết lý thiết kế khác nhau, nhưng lập luận về việc tạo ra các tác dụng phụ vẫn có thể được áp dụng, và F # gần hơn với chức năng "thuần khiết" hơn C#. –