C# 您将如何实现IEnumerator接口?
我有一个将对象映射到对象的类,但与dictionary不同的是,它以两种方式映射对象。我现在正在尝试实现一个自定义的C# 您将如何实现IEnumerator接口?,c#,.net,collections,ienumerable,ienumerator,C#,.net,Collections,Ienumerable,Ienumerator,我有一个将对象映射到对象的类,但与dictionary不同的是,它以两种方式映射对象。我现在正在尝试实现一个自定义的IEnumerator接口,该接口可以遍历这些值 public class Mapper<K,T> : IEnumerable<T>, IEnumerator<T> { C5.TreeDictionary<K,T> KToTMap = new TreeDictionary<K,T>(); C5.HashD
IEnumerator
接口,该接口可以遍历这些值
public class Mapper<K,T> : IEnumerable<T>, IEnumerator<T>
{
C5.TreeDictionary<K,T> KToTMap = new TreeDictionary<K,T>();
C5.HashDictionary<T,K> TToKMap = new HashDictionary<T,K>();
public void Add(K key, T value)
{
KToTMap.Add(key, value);
TToKMap.Add(value, key);
}
public int Count
{
get { return KToTMap.Count; }
}
public K this[T obj]
{
get
{
return TToKMap[obj];
}
}
public T this[K obj]
{
get
{
return KToTMap[obj];
}
}
public IEnumerator<T> GetEnumerator()
{
return KToTMap.Values.GetEnumerator();
}
public T Current
{
get { throw new NotImplementedException(); }
}
public void Dispose()
{
throw new NotImplementedException();
}
object System.Collections.IEnumerator.Current
{
get { throw new NotImplementedException(); }
}
public bool MoveNext()
{
;
}
public void Reset()
{
throw new NotImplementedException();
}
}
公共类映射器:IEnumerable,IEnumerator
{
C5.TreeDictionary KToTMap=新的TreeDictionary();
C5.HashDictionary TToKMap=新HashDictionary();
公共无效添加(K键,T值)
{
KToTMap.Add(键、值);
TToKMap.Add(值、键);
}
公共整数计数
{
获取{return KToTMap.Count;}
}
公共K本[T obj]
{
得到
{
返回TToKMap[obj];
}
}
这是一个公共问题[K obj]
{
得到
{
返回KToTMap[obj];
}
}
公共IEnumerator GetEnumerator()
{
返回KToTMap.Values.GetEnumerator();
}
公共电流
{
获取{抛出新的NotImplementedException();}
}
公共空间处置()
{
抛出新的NotImplementedException();
}
对象System.Collections.IEnumerator.Current
{
获取{抛出新的NotImplementedException();}
}
公共图书馆
{
;
}
公共无效重置()
{
抛出新的NotImplementedException();
}
}
使用收益回报率
只需实现
IEnumerable
接口即可。无需实现IEnumerator
,除非您想在枚举器中执行一些特殊的操作,对于您的情况来说,似乎不需要这样做
public class Mapper<K,T> : IEnumerable<T> {
public IEnumerator<T> GetEnumerator()
{
return KToTMap.Values.GetEnumerator();
}
}
公共类映射器:IEnumerable{
公共IEnumerator GetEnumerator()
{
返回KToTMap.Values.GetEnumerator();
}
}
就这样。首先,不要让集合对象实现IEnumerator。这会导致错误。(考虑两个线程在同一集合上迭代的情况) 正确实现枚举器并不是件容易的事,因此C#2.0基于“yield-return”语句为实现它添加了特殊的语言支持 雷蒙德·陈(Raymond Chen)最近的一系列博客文章(“C#中迭代器的实现及其后果”)是一个了解最新情况的好地方
- 第1部分:
- 第2部分:
- 第3部分:
- 第4部分:
CreateEnumerable()
返回一个实现getEnumerable()的IEnumerable
公共类EasyEnumerable:IEnumerable{
IEnumerable CreateEnumerable(){
收益率123;
收益率456;
对于(int i=0;i<6;i++){
收益率i;
}//为了
}//方法
公共IEnumerator GetEnumerator(){
返回CreateEnumerable().GetEnumerator();
}//方法
IEnumerator IEnumerable.GetEnumerator(){
返回CreateEnumerable().GetEnumerator();
}//方法
}//阶级
以下是罗伯特·塞吉威克的《算法》(第四版)一书中的一个例子
它是用java编写的,我基本上是用C#重写的
公共类堆栈:IEnumerable
{
私有T[]数组;
公共堆栈(int n)
{
数组=新的T[n];
}
公共堆栈()
{
数组=新的T[16];
}
公共无效推送(T项)
{
if(Count==array.Length)
{
增长(array.Length*2);
}
数组[Count++]=项;
}
公共广播电台
{
if(Count==array.Length/4)
{
收缩(数组长度/2);
}
返回数组[--Count];
}
私有空间增长(整数大小)
{
var-temp=数组;
数组=新的T[大小];
数组复制(临时、数组、临时长度);
}
私有空间收缩(整数大小)
{
阵列温度=阵列温度;
数组=新的T[大小];
复制(临时,0,数组,0,大小);
}
公共整数计数{get;私有集;}
公共IEnumerator GetEnumerator()
{
返回新的ReverseArrayIterator(计数,数组);
}
IEnumerator IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
//IEnumerator实现
私有类ReverseArrayIterator:IEnumerator
{
私人互联网i;
私有只读T[]数组;
公共ReverseArrayIterator(整数计数,T[]数组)
{
i=计数;
this.array=数组;
}
公共空间处置()
{
}
公共图书馆
{
返回i>0;
}
公共无效重置()
{
}
公共T当前{get{return array[--i];}}
对象IEnumerator.Current
{
获取{返回当前;}
}
}
}
我一开始就是这样做的,但后来意识到我希望在此对象上使用for each来获取值。要在对象上使用foreach,唯一的要求是它有一个publi GetEnumerator()方法,该方法返回和IEnumerator,对象甚至不必实现任何接口,但建议您实现IEnumerable或IEnumerable,您可以猜出原因;)我就是这么想的,所以我的错误在别处。谢谢你的安慰。
public class EasyEnumerable : IEnumerable<int> {
IEnumerable<int> CreateEnumerable() {
yield return 123;
yield return 456;
for (int i = 0; i < 6; i++) {
yield return i;
}//for
}//method
public IEnumerator<int> GetEnumerator() {
return CreateEnumerable().GetEnumerator();
}//method
IEnumerator IEnumerable.GetEnumerator() {
return CreateEnumerable().GetEnumerator();
}//method
}//class
public class Stack<T> : IEnumerable<T>
{
private T[] array;
public Stack(int n)
{
array = new T[n];
}
public Stack()
{
array = new T[16];
}
public void Push(T item)
{
if (Count == array.Length)
{
Grow(array.Length * 2);
}
array[Count++] = item;
}
public T Pop()
{
if (Count == array.Length/4)
{
Shrink(array.Length/2);
}
return array[--Count];
}
private void Grow(int size)
{
var temp = array;
array = new T[size];
Array.Copy(temp, array, temp.Length);
}
private void Shrink(int size)
{
Array temp = array;
array = new T[size];
Array.Copy(temp,0,array,0,size);
}
public int Count { get; private set; }
public IEnumerator<T> GetEnumerator()
{
return new ReverseArrayIterator(Count,array);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
// IEnumerator implementation
private class ReverseArrayIterator : IEnumerator<T>
{
private int i;
private readonly T[] array;
public ReverseArrayIterator(int count,T[] array)
{
i = count;
this.array = array;
}
public void Dispose()
{
}
public bool MoveNext()
{
return i > 0;
}
public void Reset()
{
}
public T Current { get { return array[--i]; } }
object IEnumerator.Current
{
get { return Current; }
}
}
}