我知道如何实现非泛型的IEnumerable,像这样:
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;
添加到using指令中,然后更改:
class MyObjects : IEnumerable
致:
class MyObjects : IEnumerable<MyObject>
然后右键单击IEnumerable<MyObject>
并选择Implement Interface => Implement Interface
,Visual Studio会添加以下代码块:
IEnumerator<MyObject> IEnumerable<MyObject>.GetEnumerator()
{
throw new NotImplementedException();
}
从GetEnumerator();
方法返回非泛型IEnumerable对象这次不起作用,所以我在这里放什么呢?CLI现在忽略非泛型实现,并在foreach循环期间尝试枚举我的数组时直接指向泛型版本。
7条答案
按热度按时间mw3dktmi1#
如果您选择使用泛型集合,例如
List<MyObject>
而不是ArrayList
,您会发现List<MyObject>
将提供您可以使用的泛型和非泛型枚举器。bq3bfh9z2#
您可能不需要
IEnumerable<T>
的 * 显式 * 实现(这就是您所展示的)。通常的模式是在
IEnumerable
的显式实现中使用IEnumerable<T>
的GetEnumerator
:bz4sfanl3#
为什么要手动操作?
yield return
自动化处理迭代器的整个过程。(我还写了关于它的on my blog,包括查看编译器生成的代码)。如果你真的想自己做,你也必须返回一个泛型枚举数。您将不能再使用
ArrayList
,因为它是非泛型的。将其改为List<MyObject>
。当然,这是假设集合中只有MyObject
类型(或派生类型)的对象。2w2cym1i4#
如果使用泛型,请使用List而不是ArrayList。List具有您需要的GetEnumerator方法。
iqjalb3h5#
将mylist转换为
List<MyObject>
是一种选择5n0oy7gb6#
请注意,
IEnumerable<T>
已经由System.Collections
实现,所以另一种方法是从System.Collections
派生MyObjects
类作为基类(documentation):System.Collections:为泛型集合提供基类。
我们可以稍后进行自己的实现来覆盖虚拟
System.Collections
方法以提供自定义行为(仅适用于ClearItems
、InsertItem
、RemoveItem
和SetItem
沿着Equals
、GetHashCode
和ToString
)。不像List<T>
,它的设计不容易扩展。示例:
请注意,仅在需要自定义收集行为的情况下,才建议从
collection
驱动,这种情况很少发生。参见usage。eni9jsuy7#
.....不要忘记使用,如果你被阻止
添加此内容:
此外:
这是一个很好的例子,因为它包含了IEnumerable:
...还要注意enumrAble中的A和enumratOr中的o之间的语法笑话,这两个都在这个模式中使用!漂亮的危险线: