推荐答案
在 C# 中,要实现自定义集合类并支持 foreach 循环,需要实现 IEnumerable 接口或 IEnumerable<T> 泛型接口。以下是实现自定义集合类并支持 foreach 循环的示例代码:
// www.javascriptcn.com code example
using System;
using System.Collections;
public class MyCollection : IEnumerable
{
private int[] _items;
public MyCollection(int[] items)
{
_items = items;
}
public IEnumerator GetEnumerator()
{
return new MyEnumerator(_items);
}
private class MyEnumerator : IEnumerator
{
private int[] _items;
private int _index = -1;
public MyEnumerator(int[] items)
{
_items = items;
}
public object Current
{
get
{
if (_index == -1 || _index >= _items.Length)
{
throw new InvalidOperationException();
}
return _items[_index];
}
}
public bool MoveNext()
{
_index++;
return _index < _items.Length;
}
public void Reset()
{
_index = -1;
}
}
}
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
MyCollection myCollection = new MyCollection(numbers);
foreach (var item in myCollection)
{
Console.WriteLine(item);
}
}
}本题详细解读
1. 实现 IEnumerable 接口
IEnumerable 接口是 C# 中所有集合类的基础接口。它定义了一个方法 GetEnumerator(),该方法返回一个 IEnumerator 对象。IEnumerator 对象用于遍历集合中的元素。
2. 实现 IEnumerator 接口
IEnumerator 接口定义了三个成员:
Current:获取集合中的当前元素。MoveNext():将枚举器推进到集合的下一个元素。Reset():将枚举器设置为其初始位置,即集合的第一个元素之前。
3. 自定义集合类
在自定义集合类中,我们实现了 IEnumerable 接口,并在 GetEnumerator() 方法中返回一个自定义的 IEnumerator 对象。这个自定义的 IEnumerator 对象负责遍历集合中的元素。
4. 使用 foreach 循环
foreach 循环依赖于 IEnumerable 接口。当你在自定义集合类上使用 foreach 循环时,C# 编译器会自动调用 GetEnumerator() 方法来获取枚举器,并使用该枚举器遍历集合中的元素。
5. 泛型版本
如果你希望自定义集合类支持泛型,可以实现 IEnumerable<T> 接口。IEnumerable<T> 接口与 IEnumerable 接口类似,但它返回的是 IEnumerator<T> 对象,而不是 IEnumerator 对象。IEnumerator<T> 接口提供了类型安全的 Current 属性。
// www.javascriptcn.com code example
using System;
using System.Collections;
using System.Collections.Generic;
public class MyCollection<T> : IEnumerable<T>
{
private T[] _items;
public MyCollection(T[] items)
{
_items = items;
}
public IEnumerator<T> GetEnumerator()
{
return new MyEnumerator(_items);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private class MyEnumerator : IEnumerator<T>
{
private T[] _items;
private int _index = -1;
public MyEnumerator(T[] items)
{
_items = items;
}
public T Current
{
get
{
if (_index == -1 || _index >= _items.Length)
{
throw new InvalidOperationException();
}
return _items[_index];
}
}
object IEnumerator.Current => Current;
public bool MoveNext()
{
_index++;
return _index < _items.Length;
}
public void Reset()
{
_index = -1;
}
public void Dispose()
{
// 通常不需要实现,除非有需要释放的资源
}
}
}
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
MyCollection<int> myCollection = new MyCollection<int>(numbers);
foreach (var item in myCollection)
{
Console.WriteLine(item);
}
}
}在这个泛型版本中,MyCollection<T> 类实现了 IEnumerable<T> 接口,并且 MyEnumerator 类实现了 IEnumerator<T> 接口。这使得集合类可以支持类型安全的遍历。