现在搜索网页几个小时后,我仍然无法理解IEnumerable
/ IEnumerator
如何运作以及如何实施。
我从头开始构建了一个简单的LinkedList
但现在我想为它实现IEnumerable
所以我可以预先知道它。我该怎么做?
class Program
{
LL myList = new LL();
static void Main()
{
var gogo = new Program();
}
public Program()
{
myList.Add("test");
myList.Add("test1");
foreach (var item in myList) //This doesn't work because I havn't implemented Ienumerable
Console.WriteLine(item);
Console.Read();
}
}
class LL
{
private LLNode first;
public void Add(string s)
{
if (this.first == null)
this.first = new LLNode() { Value = s };
else
{
var node = this.first;
while (node.Next != null)
node = node.Next;
node.Next = new LLNode() { Value = s };
}
}
class LLNode
{
public string Value { get; set; }
public LLNode Next { get; set; }
}
答案 0 :(得分:6)
真的不是那么难。要实施IEnumerable,您只需要实施GetEnumerator
方法。
为此,您需要创建另一个实现IEnumerator的类。实现IEnumerator非常简单。通常,在创建枚举器时(在GetEnumerator中),您将传递对集合的引用,并且枚举器将跟踪哪个项目是当前项目。然后它会提供MoveNext
,只会将Current
更改为下一个项目(如果它位于列表末尾则返回false)和Reset
只会将Current
设置为public class MyLinkedListEnumerator : IEnumerator
{
private LL myList;
private LLNode current;
public object Current
{
get { return current; }
}
public MyLinkedListEnumerator(LL myList)
{
this.myList = myList;
}
public bool MoveNext()
{
if (current == null) {
current = myList.first;
}
else {
current = current.Next;
}
return current != null;
}
public void Reset()
{
current = null;
}
}
之前第一个节点。
因此,在非常广泛的未经测试的代码术语中,您需要以下内容:
{{1}}
答案 1 :(得分:3)
您需要做的是:
(1)让你的类实现IEnumerable< T>其中T是枚举项的类型。 (在你的情况下,它看起来像是LLNode)。
(2)写一个公共IEnumerator< T> GetEnumerator的。使用“yield”关键字实现它。
(3)添加IEnumerator IEnumerable.GetEnumerator()方法,只返回GetEnumerator()。
以下代码应该明确这一点。在我有< int>的地方,你应该把< LLNode>,假设它是正确的类型。
using System;
using System.Collections;
using System.Collections.Generic;
namespace Demo
{
internal class Program
{
private static void Main()
{
var test = new MyDemo();
foreach (int item in test)
{
Console.WriteLine(item);
}
}
}
public class MyDemo: IEnumerable<int>
{
public IEnumerator<int> GetEnumerator()
{
// Your implementation of this method will iterate over your nodes
// and use "yield return" to return each one in turn.
for (int i = 10; i <= 20; ++i)
{
yield return i;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
我会修改你的代码来正确地完成它,但你发布的代码将无法编译。
[编辑]
现在您已经更新了代码,我可以看到您想要枚举值。这是完成的代码:
using System;
using System.Collections;
using System.Collections.Generic;
namespace Demo
{
internal class Program
{
private LL myList = new LL();
private static void Main()
{
var gogo = new Program();
}
public Program()
{
myList.Add("test");
myList.Add("test1");
foreach (var item in myList) // This now works.
Console.WriteLine(item);
Console.Read();
}
}
internal class LL: IEnumerable<string>
{
private LLNode first;
public void Add(string s)
{
if (this.first == null)
this.first = new LLNode
{
Value = s
};
else
{
var node = this.first;
while (node.Next != null)
node = node.Next;
node.Next = new LLNode
{
Value = s
};
}
}
public IEnumerator<string> GetEnumerator()
{
for (var node = first; node != null; node = node.Next)
{
yield return node.Value;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private class LLNode
{
public string Value { get; set; }
public LLNode Next { get; set; }
}
}
}