Linq 结果有问题
您好,我遇到了一些应该对某些 IEnumerator 对象实例执行操作的方法的问题,代码示例显示了这种情况:
class Program
{
static void Main(string[] args)
{
string[] testArray = { "Item1", "Item2" };
var query = testArray.Select((item, index) => new { index, item });
Console.WriteLine("Query run 1, {0}", Environment.NewLine);
foreach (var obj in query)
{
Console.WriteLine("{0}", obj);
}
Console.WriteLine("Query run 2, {0}", Environment.NewLine);
doAction<object>(query as IEnumerator<object>, obj => Console.WriteLine(obj) );
Console.WriteLine("Query run 3 ( same as run 1), {0}", Environment.NewLine);
foreach (var obj in query)
{
Console.WriteLine("{0}", obj);
}
Object tmp = Console.ReadLine();
}
private static void doAction<T>(IEnumerator<T> enumerator, Action<T> action)
{
if (enumerator == null)
{
throw new ArgumentNullException("enumerator");
}
if (action == null)
{
throw new ArgumentNullException("action");
}
while (enumerator.MoveNext())
{
action(enumerator.Current);
}
}
}
输出:
Query run 1,
{ index = 0, item = Item1 }
{ index = 1, item = Item2 }
Query run2,
Query run 3 ( same as run 1),
{ index = 0, item = Item1 }
{ index = 1, item = Item2 }
有谁知道什么方法 doAction
不采取操作?
真正的问题是我需要英语的答案,因为我的语气真的很糟糕,我无法解释为什么这种情况发生在我的伴侣身上。
提前致谢。
谢谢。
Hi I have had a problem with some method that should perform action on some IEnumerator object instance, the code sample shows the case:
class Program
{
static void Main(string[] args)
{
string[] testArray = { "Item1", "Item2" };
var query = testArray.Select((item, index) => new { index, item });
Console.WriteLine("Query run 1, {0}", Environment.NewLine);
foreach (var obj in query)
{
Console.WriteLine("{0}", obj);
}
Console.WriteLine("Query run 2, {0}", Environment.NewLine);
doAction<object>(query as IEnumerator<object>, obj => Console.WriteLine(obj) );
Console.WriteLine("Query run 3 ( same as run 1), {0}", Environment.NewLine);
foreach (var obj in query)
{
Console.WriteLine("{0}", obj);
}
Object tmp = Console.ReadLine();
}
private static void doAction<T>(IEnumerator<T> enumerator, Action<T> action)
{
if (enumerator == null)
{
throw new ArgumentNullException("enumerator");
}
if (action == null)
{
throw new ArgumentNullException("action");
}
while (enumerator.MoveNext())
{
action(enumerator.Current);
}
}
}
The output:
Query run 1,
{ index = 0, item = Item1 }
{ index = 1, item = Item2 }
Query run2,
Query run 3 ( same as run 1),
{ index = 0, item = Item1 }
{ index = 1, item = Item2 }
Does anyone know what method doAction
do not take action ?
The real problem is that i need the answer in English language, because my is really bad and i can not explain why this is happening to my mate.
Thanks in advance.
Thnaks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的 - 您不应该直接使用
IEnumerator
,而只能使用IEnumerable
。基本上,您会看到 C# 编译器实现迭代器块的方式很奇怪:有一种类型同时实现IEnumerable
和IEnumerator。
。这本身很不寻常,但这样做是出于性能原因。这不是您应该利用或依赖的东西。从根本上来说,将
IEnumerable
转换为IEnumerator
是一个坏主意 - 您不应该这样做。它们是不同的接口,代表着微妙不同的想法——“可以迭代的序列”和“正在序列上迭代的东西”之间的区别。如果您确实想要使用
IEnumerator
作为doAction
的参数类型(通常是DoAction
,顺便说一句)只需调用GetEnumerator()
即可:Yes - you shouldn't be using
IEnumerator<T>
directly, onlyIEnumerable<T>
. Basically you're seeing an oddity of the way that the C# compiler implements iterator blocks: there's one type which implements bothIEnumerable<T>
andIEnumerator<T>
. That's unusual in itself, but is done for performance reasons. It's not something you should take advantage of or rely on.Fundamentally, casting an
IEnumerable<T>
toIEnumerator<T>
is a bad idea - you shouldn't do it. They're different interfaces representing subtly different ideas - the difference between "a sequence which can be iterated over" and "something which is iterating over a sequence".If you really want to use
IEnumerator<T>
as the parameter type fordoAction
(which would normally beDoAction
, btw) just callGetEnumerator()
instead: