如何在不使用Annotation-specified bean name 'queueHelper' for bean class [com.x.library.utils.QueueHelper] conflicts with existing, non-compatible bean definition of same name and class [com.x.document.utils.QueueHelper]
关键字的情况下重写GetEnumerator
方法?
方法代码:
yield
我只知道如何手动实施。
答案 0 :(得分:7)
实际上,yield
语句是syntactic sugar,它使编译器实际生成一个实现IEnumerator<T>
接口的类,并使用{{1}重写方法体。语句进入状态机。
每个状态都与最终生成序列中下一个元素的代码部分相关联。这嵌入在yield
方法中。状态机可以表示所有必要的构造(序列,选择,迭代),因此所有C#代码(意味着方法中的语句)都可以像这样重写。这是潜在的魔法&#39; MoveNext()
。
在您的特定情况下,重写到状态机以及yield
(及其继承的IEnumerator<T>
(非通用)和IEnumerator
接口)的相应完整实现将看起来像这样:
IDisposable
每次调用public class CustomEnumerator : IEnumerator<int>
{
public int Current { get; private set; }
object IEnumerator.Current => this.Current;
// internal 'position' in the sequence, i.e. the current state of the state machine
private int position = 0;
public bool MoveNext()
{
// advance to next state
// (works for linear algorithms; an alternative is to select the next state at the end of processing the current state)
position++;
// perform the code associated with the current state and produce an element
switch (position)
{
// state 1: line 'yield return 1;'
case 1:
Current = 1;
return true;
// state 2: lines 'Console.WriteLine("1");' and 'yield return 2;'
case 2:
Console.WriteLine("1"); // see also note at the end of this answer
Current = 2;
return true;
// there are no other states in this state machine
default:
return false;
}
}
public void Reset()
{
position = 0;
}
public void Dispose()
{
// nothing to do here
}
}
,这是MoveNext()
语句的每次迭代内部发生的事情,会导致部分代码被执行 - 直到生成序列中的下一个元素。 / p>
为了使这个实现可用,相应的foreach
实现是必要的,这是非常简单的:
IEnumerable<T>
然后,以下两个public class CustomEnumerable : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator()
{
return new CustomEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
循环将产生完全相同的结果:
foreach
注意:在您的void Main()
{
// custom implementation of IEnumerator<T>
foreach (int i in new CustomEnumerable())
{
Console.WriteLine(i);
}
// your original implementation—will produce same results
// note: I assume someObject implements IEnumerable<T> and hence your GetEnumerator() method
foreach (int i in someObject)
{
Console.WriteLine(i);
}
}
代码中,{/ 1}}之后的调用枚举数返回GetEnumerator()
(并且调用者处理它),以便看起来有点奇怪。