Saya tahu bagaimana menerapkan IEnumerable non generik, seperti ini:
using System;
using System.Collections;
namespace ConsoleApplication33
{
class Program
{
static void Main(string[] args)
{
MyObjects myObjects = new MyObjects();
myObjects[0] = new MyObject() { Foo = "Hello", Bar = 1 };
myObjects[1] = new MyObject() { Foo = "World", Bar = 2 };
foreach (MyObject x in myObjects)
{
Console.WriteLine(x.Foo);
Console.WriteLine(x.Bar);
}
Console.ReadLine();
}
}
class MyObject
{
public string Foo { get; set; }
public int Bar { get; set; }
}
class MyObjects : IEnumerable
{
ArrayList mylist = new ArrayList();
public MyObject this[int index]
{
get { return (MyObject)mylist[index]; }
set { mylist.Insert(index, value); }
}
IEnumerator IEnumerable.GetEnumerator()
{
return mylist.GetEnumerator();
}
}
}
Namun saya juga memperhatikan bahwa IEnumerable memiliki versi generik IEnumerable<T>
, tetapi saya tidak tahu cara menerapkannya.
Jika saya menambahkan using System.Collections.Generic;
ke petunjuk penggunaan saya, dan kemudian mengubah:
class MyObjects : IEnumerable
untuk:
class MyObjects : IEnumerable<MyObject>
Dan kemudian klik kanan IEnumerable<MyObject>
dan pilih Implement Interface => Implement Interface
, Visual Studio dengan membantu menambahkan blok kode berikut:
IEnumerator<MyObject> IEnumerable<MyObject>.GetEnumerator()
{
throw new NotImplementedException();
}
Mengembalikan objek IEnumerable non generik dari GetEnumerator();
metode tidak berfungsi kali ini, jadi apa yang harus saya taruh di sini? CLI sekarang mengabaikan implementasi non generik dan langsung menuju ke versi generik ketika mencoba untuk menghitung melalui array saya selama loop foreach.
this.GetEnumerator()
dan hanya kembaliGetEnumerator()
?Collection<MyObject>
dan kemudian Anda tidak perlu menulis kode khusus apa pun.List<T>
dan menerapkanIEnumerable<T>
seperti yang ditunjukkan dalam jawaban Anda.Anda mungkin tidak menginginkan implementasi eksplisit
IEnumerable<T>
(seperti yang telah Anda tunjukkan).Pola yang biasa adalah dengan menggunakan
IEnumerable<T>
'sGetEnumerator
dalam pelaksanaan eksplisitIEnumerable
:sumber
IEnumerable
itu mubazir (IEnumerable<T>
sudah diwarisi darinya).Mengapa Anda melakukannya secara manual?
yield return
mengotomatiskan seluruh proses penanganan iterator. (Saya juga menulis tentang itu di blog saya , termasuk melihat kode yang dihasilkan kompiler).Jika Anda benar-benar ingin melakukannya sendiri, Anda harus mengembalikan enumerator generik juga. Anda tidak akan dapat menggunakan
ArrayList
lagi karena itu non-generik. Ubah ke aList<MyObject>
sebagai gantinya. Itu tentu saja mengasumsikan bahwa Anda hanya memiliki objek bertipeMyObject
(atau tipe turunan) dalam koleksi Anda.sumber
yield return
. Saya salah berasumsi bahwa ada beberapa pemrosesan khusus.Jika Anda bekerja dengan obat generik, gunakan List, bukan ArrayList. List tersebut memiliki metode GetEnumerator yang Anda butuhkan.
sumber
membuat mylist menjadi
List<MyObject>
, adalah salah satu pilihansumber
Perhatikan bahwa semua
IEnumerable<T>
sudah diimplementasikan olehSystem.Collections
jadi pendekatan lain adalah untuk menurunkanMyObjects
kelas Anda dariSystem.Collections
sebagai kelas dasar ( dokumentasi ):Kami kemudian dapat membuat implemenation kita sendiri untuk menimpa virtual
System.Collections
metode untuk memberikan perilaku kustom (hanya untukClearItems
,InsertItem
,RemoveItem
, danSetItem
bersama denganEquals
,GetHashCode
, danToString
dariObject
). Berbeda denganList<T>
yang tidak didesain agar mudah dikembangkan.Contoh:
Harap dicatat bahwa mengemudi dari yang
collection
disarankan hanya jika diperlukan perilaku pengumpulan khusus, yang jarang terjadi. lihat penggunaan .sumber