为什么尽管GetEnumerator和foreach工作正常,但我无法使用OrderBy?
为什么尽管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日
一个枚举器就是一个迭代器。它只是一个接口,告诉运行时或自定义代码如何移动到某个序列的下一个元素,重新将迭代设置为第一个元素或获取迭代中的当前元素。
也就是说,枚举器不是枚举。可枚举的对象可以创建一个枚举器,让其他代码对枚举进行枚举。
为了能够调用LINQ扩展方法,您需要将对象设为可枚举。您的Test
类没有实现IEnumerable
(LINQ扩展方法签名看起来像这样:public static IEnumerable
)。
由于我想在我的代码上应用DRY原则(不要重复自己),如果你想知道如何实现IEnumerable
,您可以看一下以下问答:如何实现IEnumerable
你必须实现接口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(); } }