尽管 GetEnumerator 和 foreach 运行良好,但为什么我不能使用 OrderBy?
Why I can't use OrderBy despite having GetEnumerator and foreach working well?
我已经为一个简单的 class 实现了 GetEnumerator
方法,令我惊讶的是我无法使用 linq 对枚举器进行排序(对 this.OrderBy(x => x)
的调用无效)。有人可以解释一下这里发生了什么吗?我是在做错什么还是枚举数只是为了迭代?
class Test
{
private Dictionary<int, string> dict
= new Dictionary<int, string>();
public IEnumerator<int> GetEnumerator()
{
return dict.Keys.GetEnumerator();
}
public Test()
{
dict[1] = "test";
dict[2] = "nothing";
}
public IEnumerable<int> SortedKeys
{
get { return this.OrderBy(x => x); } // illegal!
}
public void Print()
{
foreach(var key in this)
Console.WriteLine(dict[key]);
}
}
您必须实现接口 IEnumerable<int>
才能让 this.OrderBy
工作,否则它怎么知道 this
可以枚举 int
s?
OrderBy
需要 this
来实现 IEnumerable<T>
。它不知道您的 GetEnumerator
方法实际上是试图遵守接口。
foreach
只需要一个GetEnumerator()
方法,不需要接口实现。
// put in the interface
class Test : IEnumerable<int>
{
private Dictionary<int, string> dict
= new Dictionary<int, string>();
public IEnumerator<int> GetEnumerator()
{
return dict.Keys.GetEnumerator();
}
public Test()
{
dict[1] = "test";
dict[2] = "nothing";
}
public IEnumerable<int> 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();
}
}
OrderBy()
是 IEnumerable<T>
上的扩展方法。
您的 class 没有实现 IEnumerable<T>
.
foreach
仍然有效,因为它不需要您实施 IEnumerable<T>
;它只需要有一个方法 GetEnumerator()
.
所以你需要做的就是添加:
class Test : IEnumerable<int>
并提供非泛型的实现 IEnumerable
:
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
枚举器是迭代器。它只是一个接口,告诉运行时或自定义代码如何移动到某个序列中的下一个元素、再次将迭代重置为第一个元素或获取迭代中的当前元素。
也就是说,枚举数是不可枚举的。可枚举可以创建一个枚举器让其他代码枚举枚举。
为了能够调用 LINQ 扩展方法,您需要对象 是可枚举的。您的 Test
class 未实现 IEnumerable<T>
(LINQ 扩展方法签名如下所示:public static IEnumerable<T> Whatever<T>(this IEnumerable<T> someEnumerable)
)。
因为我想对自己应用DRY原则(Don't Repeat Yourself),如果你想知道如何实现IEnumerable<T>
你应该看看下面的问答:How do I implement IEnumerable<T>。
我已经为一个简单的 class 实现了 GetEnumerator
方法,令我惊讶的是我无法使用 linq 对枚举器进行排序(对 this.OrderBy(x => x)
的调用无效)。有人可以解释一下这里发生了什么吗?我是在做错什么还是枚举数只是为了迭代?
class Test
{
private Dictionary<int, string> dict
= new Dictionary<int, string>();
public IEnumerator<int> GetEnumerator()
{
return dict.Keys.GetEnumerator();
}
public Test()
{
dict[1] = "test";
dict[2] = "nothing";
}
public IEnumerable<int> SortedKeys
{
get { return this.OrderBy(x => x); } // illegal!
}
public void Print()
{
foreach(var key in this)
Console.WriteLine(dict[key]);
}
}
您必须实现接口 IEnumerable<int>
才能让 this.OrderBy
工作,否则它怎么知道 this
可以枚举 int
s?
OrderBy
需要 this
来实现 IEnumerable<T>
。它不知道您的 GetEnumerator
方法实际上是试图遵守接口。
foreach
只需要一个GetEnumerator()
方法,不需要接口实现。
// put in the interface
class Test : IEnumerable<int>
{
private Dictionary<int, string> dict
= new Dictionary<int, string>();
public IEnumerator<int> GetEnumerator()
{
return dict.Keys.GetEnumerator();
}
public Test()
{
dict[1] = "test";
dict[2] = "nothing";
}
public IEnumerable<int> 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();
}
}
OrderBy()
是 IEnumerable<T>
上的扩展方法。
您的 class 没有实现 IEnumerable<T>
.
foreach
仍然有效,因为它不需要您实施 IEnumerable<T>
;它只需要有一个方法 GetEnumerator()
.
所以你需要做的就是添加:
class Test : IEnumerable<int>
并提供非泛型的实现 IEnumerable
:
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
枚举器是迭代器。它只是一个接口,告诉运行时或自定义代码如何移动到某个序列中的下一个元素、再次将迭代重置为第一个元素或获取迭代中的当前元素。
也就是说,枚举数是不可枚举的。可枚举可以创建一个枚举器让其他代码枚举枚举。
为了能够调用 LINQ 扩展方法,您需要对象 是可枚举的。您的 Test
class 未实现 IEnumerable<T>
(LINQ 扩展方法签名如下所示:public static IEnumerable<T> Whatever<T>(this IEnumerable<T> someEnumerable)
)。
因为我想对自己应用DRY原则(Don't Repeat Yourself),如果你想知道如何实现IEnumerable<T>
你应该看看下面的问答:How do I implement IEnumerable<T>。