2009-10-11 31 views
5

Có bất kỳ phương pháp hay nhất nào về việc trả lại các loại trả lại khác nhau về các phương thức quá tải không? Ví dụ nếu tôi có một phương pháp tải trong DAL của tôi, tôi hoặc muốn tải một mục duy nhất hoặc một loạt các mục. Tôi biết rằng tôi có thể sử dụng một số phương pháp:Tôi có nên sử dụng các loại trả lại khác nhau trên các phương thức quá tải không?

tải một đối tượng

MyBusinessObject LoadOne(int id) 
{ 
} 

tải nhiều đối tượng

MyBusinessObject[] LoadMany(params int[] ids) 
{ 
} 

Bây giờ điều mà tôi biết tôi thể làm là quá tải một phương pháp và có các loại trả về khác nhau. Cũng giống như vậy:

MyBusinessObject Load(int id) 
{ 
} 

MyBusinessObject[] Load(params int[] ids) 
{ 
} 

Trong khi có vẻ như không có gì để ngăn cản tôi làm điều này là, và nó giữ mọi thứ gọn gàng từ một góc độ API, điều này có vẻ như là một ý tưởng tốt? Tôi đã đi qua nó đêm qua và một phần của tôi nghĩ rằng tôi không nên làm điều này vì lý do muốn kết hợp các loại trả lại cho phương pháp quá tải.

Tôi cũng có thể có phương thức Tải (int id) trả về bộ sưu tập chỉ chứa một mục. Dường như với tôi rằng điều này vi phạm nguyên tắc ít ngạc nhiên nhất mặc dù trong đó nếu bạn đang mong đợi một mục trở lại, bạn nên trả lại mục đó, bạn không nên trả về một danh sách chứa một mục duy nhất.

Vì vậy, đây là những suy nghĩ mâu thuẫn của tôi xung quanh những ý tưởng này:

  • phương pháp quá tải tất cả nên quay lại cùng loại.
  • Nếu phương pháp làm tương tự, đừng cho họ một loạt các tên khác nhau, quá tải cùng tên phương thức. Nó làm cho mọi thứ trở nên đơn giản hơn từ quan điểm của người dùng API, họ không phải rà soát thông qua một loạt các phương thức khác nhau mà tất cả về cơ bản đều làm tương tự nhưng với các tham số khác nhau.
  • Trả lại loại rõ ràng nhất cho phương pháp, tức là nếu người dùng có khả năng mong đợi một tập hợp các mục, hãy trả về một bộ sưu tập các mặt hàng, nếu họ có khả năng mong đợi một mục duy nhất, hãy trả lại một mục.

Vì vậy, hai ý nghĩ sau này vượt trội hơn lần đầu tiên, nhưng đồng thời, ý nghĩ đầu tiên có vẻ giống như một loại thực hành tốt nhất có lập trình.

Có bất kỳ phương pháp hay nhất nào xung quanh thực tiễn này không? Tôi muốn được nghe những suy nghĩ của người khác về chủ đề này.

+0

Trong mọi trường hợp, vui lòng xem xét trả về 'IEnumerable 'thay vì mảng. Eric Lippert có một bài đăng trên blog tuyệt vời về điều này. –

+0

trả về một mảng đủ để làm nổi bật kịch bản. Tôi sẽ trả về một IEnumerable trong mã thực tế của tôi. – BenAlabaster

+0

Được rồi, tuyệt. Chỉ cần bạn biết. –

Trả lời

8

tôi có thể bị cám dỗ để làm cho API rõ ràng và sử dụng đa số trong tên:

Customer LoadCustomer(int id) {...} 
Customer[] LoadCustomers(params int[] id) {...} 

Trên thực tế, params hiếm khi hữu ích ở đây - bạn không thường biết id tại thời gian biên dịch.

+0

Trong tham chiếu đến các tham số, tôi hiểu quan điểm của bạn, nhưng tôi đã làm nổi bật một khái niệm chứ không phải là một đường dẫn mã thực tế. Tôi tưởng tượng rằng trong một kịch bản thực tế, tôi sẽ chuyển các thông tin lọc có thể trả về danh sách các mục có khả năng thay vì một mục duy nhất. Tôi thích ý tưởng của đa số, nó chắc chắn sẽ giữ cho nhiều phương pháp với nhau trong intellisense. – BenAlabaster

0

Ý tưởng cá nhân của tôi là phương pháp sau có vẻ dễ hiểu hơn từ góc độ người dùng API.

3

Bạn chỉ có thể xem một API hiện có. Ví dụ, hãy lấy LINQ, nó có phương thức "Select" trả về nhiều thực thể và phương thức "Single" chỉ trả về một thực thể. Hầu hết các API hiện có có hai phương thức khác nhau, không phải là các phương thức quá tải và tôi nghĩ điều này là hợp lý và dễ đọc hơn.

+0

Nhưng cũng có nghĩa là API của bạn được rải rác với nhiều phương pháp thực hiện tương tự. – BenAlabaster

+0

Bên cạnh đó, làm theo các API của những người khác làm ví dụ không giúp bạn hiểu quy trình suy nghĩ của họ vì đã thiết kế theo cách đó. Tôi muốn xem một nửa tá các ví dụ khác nhau * với quy trình * suy nghĩ hơn là một chuỗi các API hoàn toàn không có chúng. Bằng cách này tôi có thể đưa ra quyết định sáng suốt hơn là chỉ mù quáng theo gương của người khác. – BenAlabaster

+0

Tôi không phải là người theo dõi mù quáng =) Tôi đã viết ý kiến ​​của mình và các công nghệ hàng đầu xứng đáng được tôi chú ý ở mức tối thiểu. Nhân tiện, nhận được một thực thể và nhận được nhiều thực thể không giống nhau. – Restuta

2

Tôi có xu hướng theo điểm đầu tiên trong danh sách "suy nghĩ của bạn vượt qua ý tưởng này" cho biết "quá tải phải trả về cùng loại".

nhưng sau đó bạn có thể quá tải "LoadMany" với một số trường hợp khác nhau;

public Customer Load(int id) 
{ 
    // return just one customer 
} 

public List<Customer> LoadMany() 
{ 
    // return every single customer 
} 

public List<Customer> LoadMany(int statusFilter) 
{ 
    // return a filtered list of customers 
} 

public List<Customer> LoadMany(DateTime InitialContactFrom) 
{ 
    // return a filtered list of customers 
} 

public List<Customer> LoadMany(DateTime InitialContactFrom, DateTime InitialContactBefore) 
{ 
    // return a filtered list of customers 
} 

... bất kỳ kết hợp nào bạn cần rõ ràng có thể được thêm vào nhưng cuối cùng, LoadMany trả về danh sách và Tải trả về một thực thể.

3

Có thể có ngoại lệ, nhưng trừ khi bạn có lý do thực sự tốt để trả về các loại khác nhau, chức năng và quá tải của nó phải trả về cùng loại để bạn không khiến các nhà phát triển khác phát điên.

Ví dụ:

var a = MyFunc("Some text"); 

var a = MyFunc(1); 

cả trông giống như họ nên giải quyết var để cùng loại với tôi. Trước khi tôi đi chệch khỏi việc có tất cả các tình trạng quá tải trở về cùng một loại, tôi sẽ đảm bảo rằng tôi có một lý do rất vững chắc để trả lại các loại khác nhau.

+0

Điểm công bằng, tôi đã không xem xét quan điểm var, mà thực sự vi phạm nguyên lý của tôi làm cho mỗi dòng càng dễ hiểu càng tốt với tham chiếu đến ít mã khác nhất có thể. – BenAlabaster

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