Kembali antarmuka atau kelas

9

Misalkan saya punya metode

public List<User> GetBatchOfUsers(IEnumerable<int> userIDs)
{
    List<User> users = new List<User>();

    // some database stuff

    return users;
}

Saya telah membaca bahwa akan lebih baik untuk mengembalikan antarmuka (baik IListatau IEnumerable) daripada mengembalikan List. Beberapa argumen yang saya dengar untuk melakukannya adalah menyembunyikan data, dan memberikan pengembang API fleksibilitas untuk mengubah representasi internal data di kemudian hari.

Kekhawatiran saya hanya mengembalikan sebuah IEnumerableadalah bahwa Anda kehilangan fungsionalitas, seperti akses acak dan Countproperti.

Saya tahu bahwa menerima IEnumerablesebagai parameter masuk akal, karena memberikan konsumen fleksibilitas terbaik untuk mengirim data ke metode saya, persyaratan minimal untuk metode untuk beroperasi.

Apa praktik terbaik untuk tipe pengembalian?

Matius
sumber
5
Jauh lebih penting: menggunakan antarmuka sebagai tipe parameter.
Michael Borgwardt

Jawaban:

10

Secara umum, Anda bisa mulai dengan antarmuka, dan hanya bergerak untuk meletakkan tipe konkret sebagai tipe pengembalian jika Anda menemukan bahwa Anda menggunakan metode ekstra lebih sering dari yang diharapkan.

Nah, jika Anda mengembalikan antarmuka, Anda mempertahankan lebih banyak fleksibilitas. Anda dapat mengubah implementasi nanti untuk mengembalikan tipe beton yang berbeda. Di sisi lain, itu jelas memberikan informasi yang kurang penelepon, sehingga mereka mungkin tidak dapat melakukan operasi tertentu. (Misalnya: jika Anda kembali List<T>, penelepon dapat menggunakan ConvertAll dll ... yang tidak dapat mereka lakukan jika Anda hanya menyatakan bahwa Anda kembali IList<T>.) Dalam beberapa situasi, sebaiknya Anda menentukan jenis konkretnya.

Mengenai metode Count atau Sortir, tidak ada antarmuka pengumpulan standar untuk itu. Namun, Anda dapat menulis metode ekstensi untuk mengurutkan atau menghitung IList apa pun.

Yusubov
sumber
Saya kira ini bukan aturan yang sulit?
Matius
ya, itu benar-benar tergantung penggunaan.
Yusubov
1

Jika Anda memerlukan koleksi Anda untuk memiliki CountAnda dapat menggunakan ICollection<T>, yang cukup umum.

dpiatkowski
sumber
-1. Hitung sudah didiskusikan dan jawaban ini tidak menambah yang baru
superM
@Konrad Rudolph, ini bukan jawaban, ini komentar.
superM
@superM Cukup berharga untuk mendapatkan jawabannya sendiri, saya kira, karena ini secara eksplisit membahas alasan OP untuk memutuskan antarmuka pada awalnya.
Konrad Rudolph
1

Anda mengembalikan apa yang bijaksana untuk metode yang Anda tetapkan. Apakah yang Anda lakukan mengembalikan serangkaian item (fokus ada pada item), atau mengembalikan koleksi item (fokusnya adalah pada koleksi secara keseluruhan)? Apakah ada gunanya membiarkan perbedaan dalam implementasi koleksi? Jika tidak akan pernah masuk akal untuk menggunakan generator atau HashSethanya menggunakan List.

Telastyn
sumber
1

Khusus untuk metode contoh: Anda benar bahwa mengembalikan IEnmuerable<T>berarti Anda akan kehilangan fungsionalitas Countdan pengindeksan (meskipun Anda dapat menggunakan metode Count()dan LINQ ElementAt(), yang diterapkan secara efisien jika jenis yang mereka gunakan benar-benar mengimplementasikan IList<T>).

Jika Anda kembali IList<T>, Anda akan kehilangan beberapa fungsionalitas, tetapi keuntungan secara umum mungkin sepadan.

Tetapi bahkan lebih baik akan menjadi sesuatu di antara IEnumerable<T>dan IList<T>, karena kemungkinan besar tidak masuk akal bagi konsumen untuk mengubah koleksi yang dikembalikan, tetapi masuk akal baginya untuk menggunakan Countatau mengindeks.

Di Net 4.5, ada antarmuka seperti: IReadOnlyList<T>.

svick
sumber
IReadOnlyListkedengarannya bagus ketika saya bisa mendapatkan VS2013, terima kasih!
Matius