How do I implement IEnumerable<T>
我知道如何实现非泛型IEnumerable,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 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(); } } } |
然而,我也注意到IEnumerable有一个通用版本,即
如果我将
1 | class MyObjects : IEnumerable |
到:
1 | class MyObjects : IEnumerable<MyObject> |
然后右键单击
1 2 3 4 | IEnumerator<MyObject> IEnumerable<MyObject>.GetEnumerator() { throw new NotImplementedException(); } |
这次从
如果您选择使用通用集合,如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using System.Collections; class MyObjects : IEnumerable<MyObject> { List<MyObject> mylist = new List<MyObject>(); public MyObject this[int index] { get { return mylist[index]; } set { mylist.Insert(index, value); } } public IEnumerator<MyObject> GetEnumerator() { return mylist.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } } |
您可能不希望显式实现
通常的模式是在显式实现IEnumerable时使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class FooCollection : IEnumerable<Foo>, IEnumerable { SomeCollection<Foo> foos; // Explicit for IEnumerable because weakly typed collections are Bad System.Collections.IEnumerator IEnumerable.GetEnumerator() { // uses the strongly typed IEnumerable<T> implementation return this.GetEnumerator(); } // Normal implementation for IEnumerable<T> IEnumerator<Foo> GetEnumerator() { foreach (Foo foo in this.foos) { yield return foo; //nb: if SomeCollection is not strongly-typed use a cast: // yield return (Foo)foo; // Or better yet, switch to an internal collection which is // strongly-typed. Such as List<T> or T[], your choice. } // or, as pointed out: return this.foos.GetEnumerator(); } } |
为什么要手动操作?
如果你真的想自己做,你也必须返回一个通用的枚举器。您将无法再使用
如果使用泛型,请使用list而不是arraylist。列表中正好有您需要的getEnumerator方法。
1 |
把我的名单变成一个
请注意,
System.Collections: Provides the base class for a generic collection.
之后我们可以自己提出建议,推翻提供定制行为的虚拟
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class FooCollection : System.Collections<Foo> { //... protected override void InsertItem(int index, Foo newItem) { base.InsertItem(index, newItem); Console.Write("An item was successfully inserted to MyCollection!"); } } public static void Main() { FooCollection fooCollection = new FooCollection(); fooCollection.Add(new Foo()); //OUTPUT: An item was successfully inserted to FooCollection! } |
请注意,只有在需要自定义收集行为时,才建议从