c#list和具有属性的枚举器

时间:2013-07-17 12:08:50

标签: c# list properties enumeration

我有以下问题: 我有一个列表,并将字符串项添加到此列表中。 然后我从列表中创建一个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();
    }
}

2 个答案:

答案 0 :(得分:4)

List<T>.Enumerator是一个结构体,所以在你的while循环中,每次访问Enumerator属性时,都会调用getter,每次都会返回一个枚举器的新副本。此枚举器将指向列表开头之前的项目,并且对MoveNextCurrent的每次调用都将在该枚举器的不同副本上完成。

因此,在非空列表中,MoveNext将始终返回true,Enumerator.Current始终为空。

如果您直接访问该字段,则表示您正在避免使用此副本,并且通过调用MoveNextCurrent访问了相同的枚举数。

如果您将代码更改为:

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);
}