Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 您将如何实现IEnumerator接口?_C#_.net_Collections_Ienumerable_Ienumerator - Fatal编程技术网

C# 您将如何实现IEnumerator接口?

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

我有一个将对象映射到对象的类,但与dictionary不同的是,它以两种方式映射对象。我现在正在尝试实现一个自定义的
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; }
        }
    }
}