为什么尽管GetEnumerator和foreach工作正常,但我无法使用OrderBy?

28 浏览
0 Comments

为什么尽管GetEnumerator和foreach工作正常,但我无法使用OrderBy?

我为一个简单的类实现了GetEnumerator方法,但惊讶的发现我不能使用linq对枚举器进行排序(调用this.OrderBy(x => x)是无效的)。有人能解释一下这里发生了什么吗?我做错了什么,还是枚举器只是用来迭代的?

class Test
{
    private Dictionary<int, string> dict
        = new Dictionary<int, string>();
    public IEnumerator GetEnumerator()
    {
        return dict.Keys.GetEnumerator();
    }
    public Test()
    {
        dict[1] = "test";
        dict[2] = "nothing";
    }
    public IEnumerable SortedKeys
    {
        get { return this.OrderBy(x => x); } // illegal!
    }
    public void Print()
    {
        foreach(var key in this)
            Console.WriteLine(dict[key]);
    }
}

admin 更改状态以发布 2023年5月21日
0
0 Comments

一个枚举器就是一个迭代器。它只是一个接口,告诉运行时或自定义代码如何移动到某个序列的下一个元素,重新将迭代设置为第一个元素或获取迭代中的当前元素。

也就是说,枚举器不是枚举。可枚举的对象可以创建一个枚举器,让其他代码对枚举进行枚举。

为了能够调用LINQ扩展方法,您需要将对象设为可枚举。您的Test类没有实现IEnumerable(LINQ扩展方法签名看起来像这样:public static IEnumerable Whatever(this IEnumerable someEnumerable))。

由于我想在我的代码上应用DRY原则(不要重复自己),如果你想知道如何实现IEnumerable,您可以看一下以下问答:如何实现IEnumerable

0
0 Comments

你必须实现接口IEnumerable,才能使this.OrderBy工作,否则它怎么知道this可以枚举int

OrderBy要求this实现IEnumerable。它不知道你的GetEnumerator方法实际上是为了符合接口要求。

foreach只需要一个GetEnumerator()方法,不需要实现接口。

// put in the interface
class Test : IEnumerable
{
    private Dictionary dict
        = new Dictionary();
    public IEnumerator GetEnumerator()
    {
        return dict.Keys.GetEnumerator();
    }
    public Test()
    {
        dict[1] = "test";
        dict[2] = "nothing";
    }
    public IEnumerable SortedKeys
    {
        get { return this.OrderBy(x => x); } // illegal!
    }
    public void Print()
    {
        foreach (var key in this)
            Console.WriteLine(dict[key]);
    }
    // this one is required according to the interface too
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

0