Mengapa IList tidak mendukung AddRange

89

List.AddRange()ada, tapi IList.AddRange()tidak.
Ini menurut saya aneh. Apa alasan dibalik ini?

Boris Callens
sumber

Jawaban:

68

Karena antarmuka harus mudah diimplementasikan dan tidak berisi "segalanya kecuali dapur". Jika Anda menambahkan AddRangeAnda harus menambahkan InsertRangedan RemoveRange(untuk simetri). Pertanyaan yang lebih baik adalah mengapa tidak ada metode ekstensi untuk IList<T>antarmuka yang mirip dengan IEnumerable<T>antarmuka. (metode penyuluhan untuk di-tempat Sort, BinarySearch... akan berguna)

xanatos.dll
sumber
35
@ShdNx Mereka tidak terlalu sepele untuk diimplementasikan secara kinerja. Sebuah "internal" AddRange/RemoveRange/InsertRangedapat bekerja langsung pada pengumpulan "internal" dan mengoptimalkan Capacitypengelolaan dan menggunakan metode seperti Array.Copymemindahkan blok data. Metode ekstensi RemoveRangemungkin akan menjadi urutan magniture lebih lambat dariList.RemoveRange
xanatos
2
Sayang sekali tidak ada (dan masih belum) cara apa pun untuk antarmuka (mis. IFoo) Deklarasi untuk menentukan namespace "helper" (mis. MyAssembly) Sedemikian rupa sehingga jika kelas mengklaim untuk mengimplementasikan IFootetapi tidak memiliki metode int Bar(String), kompilator akan otomatis- menghasilkan metode int IFoo.Bar(String p1) {return MyAssembly.ClassHelpers.IFoo.Bar(this, p1);} Seandainya fitur seperti itu ada, antarmuka dapat menyertakan lebih banyak metode seperti AddRangeyang dapat diimplementasikan dalam hal perilaku dasar, tetapi beberapa implementasi dapat mengoptimalkan.
supercat
1
Mereka dapat diimplementasikan sebagai metode ekstensi, dengan begitu implementasi antarmuka tidak perlu mengimplementasikannya. Kenapa tidak?
Tom Pažourek
15
Ini tidak masuk akal. Antarmuka mengabstraksikan implementasi, sehingga bisa ada beberapa implementasi dari fitur dasar yang sama; tidak ada alasan mengapa fitur harus dihilangkan dari antarmuka, karena "penerapannya sulit". Tanpa metode seperti "AddRange" pada antarmuka, tidak ada jaminan bahwa objek yang mendasari mendukungnya, dan pada saat itu Anda dipaksa untuk mengimplementasikan ekstensi sub-optimal atau mengalahkan tujuan penggunaan antarmuka dengan membuat asumsi berbahaya mencoba untuk cast ke kelas pelaksana tertentu. Antarmuka yang dibodohi digunakan secara berlebihan.
Triynko
3
Harus ada antarmuka IRangeList yang mendukung operasi massal, yang diterapkan hanya pada beberapa koleksi yang secara internal akan memiliki implementasi yang optimal.
juga
8

Bagi mereka yang ingin memiliki metode ekstensi untuk "AddRange", "Sort", ... di IList,

Di bawah ini adalah AddRangemetode ekstensi:

 public static void AddRange<T>(this IList<T> source, IEnumerable<T> newList)
 {
     if (source == null)
     {
        throw new ArgumentNullException(nameof(source));
     }

     if (newList == null)
     {
        throw new ArgumentNullException(nameof(newList));
     }

     if (source is List<T> concreteList)
     {
        concreteList.AddRange(newList);
        return;
     }

     foreach (var element in newList)
     {
        source.Add(element);
     }
}

Saya membuat perpustakaan kecil yang melakukan ini. Saya merasa lebih praktis daripada harus mengulangi metode ekstensi pada setiap proyek.

Beberapa metode lebih lambat daripada List tetapi mereka melakukan pekerjaan itu.

Inilah GitHub yang menarik minat mereka:

Penyimpanan IListExtension

Emilien Mathieu
sumber