Pre*_*cho 6 c# ienumerable ienumerator
在网上搜索了几个小时后,我仍然无法理解如何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; }
}
Run Code Online (Sandbox Code Playgroud)
这真的不是那么难.要实现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;
}
}
Run Code Online (Sandbox Code Playgroud)
你需要做的是:
(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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我会修改您的代码以正确执行此操作,但您发布的代码无法编译。
[编辑]
现在您已经更新了代码,我可以看到您想要枚举这些值。这是完成的代码:
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; }
}
}
}
Run Code Online (Sandbox Code Playgroud)