Đây là câu hỏi về phương pháp mở rộng của C # và triết lý thiết kế của họ, vì vậy tôi nghĩ rằng cách tốt nhất để trả lời câu hỏi này là trích dẫn tài liệu của MSDN về mục đích của phương pháp mở rộng :
Các phương thức mở rộng cho phép bạn "thêm" các phương thức vào các loại hiện có mà không cần tạo một loại dẫn xuất mới, biên dịch lại hoặc sửa đổi loại ban đầu. Các phương thức mở rộng là một loại phương thức tĩnh đặc biệt, nhưng chúng được gọi như thể chúng là các phương thức thể hiện trên kiểu mở rộng. Đối với mã máy khách được viết bằng C #, F # và Visual Basic, không có sự khác biệt rõ ràng giữa việc gọi một phương thức mở rộng và các phương thức thực sự được xác định trong một loại.
Giáo dục
Nói chung, chúng tôi khuyên bạn nên thực hiện các phương pháp mở rộng một cách tiết kiệm và chỉ khi bạn phải thực hiện. Bất cứ khi nào có thể, mã máy khách phải mở rộng một loại hiện có nên làm như vậy bằng cách tạo một loại mới xuất phát từ loại hiện có. Để biết thêm thông tin, xem Kế thừa.
Khi sử dụng phương thức tiện ích mở rộng để mở rộng loại có mã nguồn bạn không thể thay đổi, bạn sẽ gặp rủi ro khi thay đổi trong việc triển khai loại sẽ khiến phương thức tiện ích mở rộng của bạn bị hỏng.
Nếu bạn thực hiện các phương thức mở rộng cho một loại nhất định, hãy nhớ các điểm sau:
- Một phương thức mở rộng sẽ không bao giờ được gọi nếu nó có cùng chữ ký với một phương thức được xác định trong loại.
- Các phương thức mở rộng được đưa vào phạm vi ở cấp độ không gian tên. Ví dụ, nếu bạn có nhiều lớp tĩnh chứa các phương thức mở rộng trong một không gian tên duy nhất được đặt tên
Extensions
, tất cả chúng sẽ được đưa vào phạm vi bởi lệnh using Extensions;
.
Tóm lại, các phương thức mở rộng được thiết kế để thêm các phương thức cá thể vào một loại cụ thể, ngay cả khi các nhà phát triển không thể làm như vậy trực tiếp. Và bởi vì các phương thức cá thể sẽ luôn ghi đè các phương thức mở rộng nếu có (nếu được gọi bằng cú pháp phương thức cá thể), điều này chỉ nên được thực hiện nếu bạn không thể trực tiếp thêm một phương thức hoặc mở rộng lớp. *
Nói cách khác, một phương thức mở rộng sẽ hoạt động giống như một phương thức cá thể, bởi vì cuối cùng nó có thể trở thành một phương thức cá thể. Và bởi vì một phương thức cá thể sẽ ném nếu đối tượng mà nó được gọi là null
, nên phương thức mở rộng cũng vậy.
* Như một lưu ý phụ, đây chính xác là tình huống mà các nhà thiết kế của LINQ phải đối mặt: khi C # 3.0 được phát hành, đã có hàng triệu khách hàng đang sử dụng System.Collections.IEnumerable
và System.Collections.Generic.IEnumerable<T>
cả trong bộ sưu tập của họ và trong foreach
các vòng lặp. Những lớp học trở lại IEnumerator
đối tượng mà chỉ có hai phương pháp Current
và MoveNext
, vì vậy thêm bất kỳ phương pháp dụ yêu cầu bổ sung, chẳng hạn như Count
, Any
vv, sẽ được phá vỡ những hàng triệu khách hàng. Vì vậy, để cung cấp chức năng này (đặc biệt là vì nó có thể được triển khai theo cách dễ dàng Current
và MoveNext
tương đối), họ đã phát hành nó dưới dạng phương thức mở rộng, có thể được áp dụng cho bất kỳ hiện tại nàoIEnumerable
cá thể và cũng có thể được các lớp thực hiện theo những cách hiệu quả hơn. Nếu các nhà thiết kế của C # quyết định phát hành LINQ vào ngày đầu tiên, nó sẽ được cung cấp dưới dạng phương thức ví dụ IEnumerable
và có lẽ họ đã thiết kế một số loại hệ thống để cung cấp các triển khai giao diện mặc định của các phương thức đó.