问题
I have the following problem:
I have a list and add string items to this list.
Then I create an Enumerator out of the list. When I loop through the list with the MoveNext()
command it works when I access the enumerator directly. When I use the Enumerator properties to access the enumerator it doesn't work. The MoveNext()
command doesn't increment the index.
Here is the code I used. Thanks a lot for your help.
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();
}
}
回答1:
List<T>.Enumerator is a struct, so in your while loop, each time you access the Enumerator
property, you are calling the getter, which will return you a new copy of the enumerator each time. This enumerator will point to the item before th beginning of the list, and each call to MoveNext
and Current
will be done on a different copy of that enumerator.
As a result on a non-empty list, MoveNext
will always return true, and Enumerator.Current
is always null.
If you access the field directly, you are avoiding this copy and the same enumerator being accessed by the calls to MoveNext
and Current
.
If you change your code to:
using (var enumerator = dummyklasse.Enumerator)
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
it will work as expected. Note this is similar to what the foreach
statement does.
回答2:
Why are you trying to capture an enumerator in your DummyKlasse
? Better just to capture the List itself (which you are doing), and let consumers worry about their own enumerators. This is best done with the use of a foreach
loop.
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);
}
来源:https://stackoverflow.com/questions/17699412/c-sharp-list-and-enumerator-with-properties