我有以下问题:
我有一个列表,并将字符串项添加到此列表中。
然后我从列表中创建一个Enumerator。当我使用MoveNext()
命令遍历列表时,它在我直接访问枚举器时起作用。当我使用Enumerator属性访问枚举器时,它不起作用。 MoveNext()
命令不会增加索引。
这是我使用的代码。非常感谢你的帮助。
public class DummyKlasse
{
public List<string>.Enumerator enumerator;
public List<string> list;
public DummyKlasse()
{
Console.WriteLine("Test");
list = new List<string>();
enumerator = new List<string>.Enumerator();
}
public List<string>.Enumerator Enumerator
{
get { return enumerator; }
set { enumerator = value;}
}
public List<string> List
{
get { return list; }
set { list = new List<string>(value); }
}
public void dummyfunction()
{
List.Add("test1");
List.Add("test2");
enumerator = List.GetEnumerator();
}
}
public class Program
{
static void Main(string[] args)
{
DummyKlasse dummyklasse = new DummyKlasse();
dummyklasse.dummyfunction();
//Does not work with properties
/*
while (dummyklasse.Enumerator.MoveNext())
{
Console.WriteLine(dummyklasse.Enumerator.Current);
}
*/
//Works WITHOUT properties
while (dummyklasse.enumerator.MoveNext())
{
Console.WriteLine(dummyklasse.enumerator.Current);
}
Console.ReadLine();
}
}
答案 0 :(得分:4)
List<T>.Enumerator
是一个结构体,所以在你的while循环中,每次访问Enumerator
属性时,都会调用getter,每次都会返回一个枚举器的新副本。此枚举器将指向列表开头之前的项目,并且对MoveNext
和Current
的每次调用都将在该枚举器的不同副本上完成。
因此,在非空列表中,MoveNext
将始终返回true,Enumerator.Current
始终为空。
如果您直接访问该字段,则表示您正在避免使用此副本,并且通过调用MoveNext
和Current
访问了相同的枚举数。
如果您将代码更改为:
using (var enumerator = dummyklasse.Enumerator)
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
它将按预期工作。请注意,这类似于foreach
语句的作用。
答案 1 :(得分:0)
您为什么要在DummyKlasse
中捕获枚举器?更好的方法是捕获List本身(你正在做的),并让消费者担心他们自己的枚举器。最好使用foreach
循环。
public class DummyKlasse
{
public List<string> List { get; set; }
public DummyKlasse()
{
List = new List<string>();
}
public void Setup()
{
List.Add("one");
List.Add("two");
}
}
...
var dummy = new DummyKlasse();
dummy.Setup();
// the client does his own enumerating, not dummy.
foreach (var str in dummy.List)
{
Console.WriteLine(str);
}