我如何实现IEnumerable <T>

我知道如何实现非genericsIEnumerable,像这样:

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有一个通用的版本, IEnumerable<T> ,但我不知道如何实现它。

如果我添加using System.Collections.Generic; 到我使用的指令,然后更改:

 class MyObjects : IEnumerable 

至:

 class MyObjects : IEnumerable<MyObject> 

然后右键单击IEnumerable<MyObject>并selectImplement Interface => Implement Interface ,Visual Studio有助于添加以下代码块:

 IEnumerator<MyObject> IEnumerable<MyObject>.GetEnumerator() { throw new NotImplementedException(); } 

GetEnumerator();返回非genericsIEnumerable对象GetEnumerator(); 方法这次不行,所以我在这里放什么? CLI现在忽略了非generics实现,并在foreach循环期间尝试枚举数组时通过generics版本。

谢谢

5 Solutions collect form web for “我如何实现IEnumerable <T>”

如果您select使用generics集合(如List<MyObject>而不是ArrayList ,则会发现List<MyObject>将提供可以使用的generics和非generics枚举器。

 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(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); } } 

你可能不希望IEnumerable<T>显式实现(这是你所显示的)。

通常的模式是在IEnumerable<T>的显式实现中使用IEnumerable<T>的GetEnumerator:

 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(); } } 

你为什么手动做? yield return自动处理迭代器的整个过程。 (我也在我的博客上写过关于它,包括编译器生成的代码)。

如果你真的想自己做,你也必须返回一个普通的枚举器。 您将无法再使用ArrayList因为这是非generics的。 改为将其更改为List<MyObject> 。 这当然假定你的集合中只有MyObject (或派生types)types的对象。

如果你使用generics,使用List而不是ArrayList。 该列表具有您需要的GetEnumerator方法。

 List<MyObject> myList = new List<MyObject>(); 

使mylist成为一个List<MyObject> ,是一个选项

  • 有界通配符相关的编译器错误
  • 调用静态generics方法
  • Lambdaexpression式和通用方法
  • 是否有可能解决“为可变参数创buildTgenerics数组”编译器警告?
  • Java枚举定义
  • 通过可变参数可能造成的堆污染
  • 在C#4.0中命名参数和genericstypes推断
  • 使用generics的c#协变返回types
  • 在genericstypes参数上调用静态方法
  • Javagenerics如何与C ++模板不同? 为什么我不能使用int作为参数?
  • 在C#generics中有没有合理的方法来“默认”types的参数?