C# 对我的对象实现IEnumerable
可能重复:C# 对我的对象实现IEnumerable,c#,ienumerable,ienumerator,C#,Ienumerable,Ienumerator,可能重复: 在网上搜索了几个小时后,我仍然无法理解IEnumerable/IEnumerator是如何工作的以及如何实现它的 我从头构建了一个简单的LinkedList,但现在我想为它实现IEnumerable,这样我就可以看到它了。我该怎么做 class Program { LL myList = new LL(); static void Main() { var gogo = new Program(); } public Pro
在网上搜索了几个小时后,我仍然无法理解
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; }
}
其实没那么难。要实现,只需实现
GetEnumerator
方法
为此,您需要创建另一个实现的类。实现IEnumerator非常简单。通常,在创建枚举器(在GetEnumerator中)时,将传递对集合的引用,枚举器将跟踪哪个项是当前项。然后,它将提供MoveNext
,它只是将当前的更改为下一项(如果在列表末尾,则返回false)和Reset
,它只是将当前的设置回第一个节点之前
因此,在非常广泛的、未经测试的代码术语中,您需要:
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) 使类实现IEnumerable,其中T是枚举项的类型。(在您的情况下,它看起来像是LLNode)
(2) 编写一个公共IEnumerator GetEnumerator。使用“yield”关键字实现它
(3) 添加IEnumerator IEnumerable.GetEnumerator()方法,然后只返回GetEnumerator()
下面的代码应该说明这一点。如果我有,你应该把,假设这是正确的类型
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();
}
}
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
名称空间演示
{
内部课程计划
{
私有静态void Main()
{
var test=newmydemo();
foreach(测试中的int项)
{
控制台写入线(项目);
}
}
}
公共类MyDemo:IEnumerable
{
公共IEnumerator GetEnumerator()
{
//此方法的实现将在节点上迭代
//并使用“收益率回报”依次回报每一项。
对于(inti=10;我不是一个在自定义类上实现IEnumerable
的好教程。是一个更好的教程。请注意,从技术上讲,不需要实现IEnumerable
就可以将类与foreach
循环一起使用……是的,我知道,但我想学习如何使用它。只是要指出,C#在这方面帮了你很多忙,如果是的话您使用yield
语句等自己创建GetEnumerator()
方法。我得到以下错误:错误1可访问性不一致:参数类型“xx.LL”的可访问性不如方法“xx.MyLinkedListEnumerator.MyLinkedListEnumerator(xx.LL)'C:\\xx\Program.cserror@Ben:这可能是因为你的LL
类是私有的。请将其标记为public。现在尝试编译它,不使用foreach循环和writele。谢谢,它现在可以工作了。现在我要学习它。
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; }
}
}
}