目录
都是迭代, 为啥我一定要用 foreach
如果换成是字典呢?
关于 foreach
都是迭代, 为啥我一定要用 foreach
? 问题起源于本人的一个练手的扑克牌程序: 洗完牌之后要发给场上的三人.
? 只发给单个人的时候用 foreach 循环一下就好了, 但三个人就有点麻烦了.
? 牌组用 list 保存你可能会想到这样写:
- for (int i = 0; i < PreCard.Count; i++)
- {
- a.Add(PreCard[i++]);
- b.Add(PreCard[i++]);
- c.Add(PreCard[i]);
- }
? 或者这样写
- int i = 0;
- do
- {
- a.Insert(i, PreCard[0]);
- b.Insert(i, PreCard[1]);
- c.Insert(i, PreCard[2]);
- PreCard.RemoveRange(0, 3);
- i++;
- } while (i < PreCard.Count);
? 但如果还想使用类似迭代器的方法, 那么可以使用 GetEnumerator(), 因为我们知道 foreach 里面实际上就是调用了这个方法.
? 所以我们还可以直接调用 GetEnumerator 和 MoveNext 来进行迭代:
- IEnumerator IE = PreCard.GetEnumerator();
- while(IE.MoveNext())
- {
- a.Add(IE.Current.ToString());
- IE.MoveNext();
- b.Add(IE.Current.ToString());
- IE.MoveNext();
- c.Add(IE.Current.ToString());
- }
如果换成是字典呢?
? 如果是直接把上面的代码搬过来, 会发现 add 方法那里会报错, 需要提供两个参数, 键和值.
? 难道必须要对得到的 IEnumerator 再用一次 GetEnumerator?
? 实际上大可不必, 因为针对这种键值对, 我们有一个玩意叫做 IDictionaryEnumerator. 看名字就知道它就是为此而生的.
- IDictionaryEnumerator IE = dict.GetEnumerator();
- while(IE.MoveNext())
- {
- a.Add(IE.Key.ToString(),Convert.ToInt32(IE.Value));
- IE.MoveNext();
- b.Add(IE.Key.ToString(),Convert.ToInt32(IE.Value));
- IE.MoveNext();
- c.Add(IE.Key.ToString(),Convert.ToInt32(IE.Value));
- }
? 至此我们通过写手动挡的 foreach , 成功的实现了可迭代对象间的赋值.
关于 foreach
? 在 C# 中 foreach 语句, 能够进行比 for 循环语句更直接和简单的对集合的迭代, 编译器会将 foreach 编译来调用 GetEnumerator 和 MoveNext 方法以及 Current 属性.
? 实际上 foreach 语句编译之后也会产生类似于上面所写的代码. 实际上这幅图可以比较清楚的说明一切.
? 当然你也可以看看我写的这篇随笔, 了解更多细节 https://www.cnblogs.com/AD-milk/p/12459944.html
来源: http://www.bubuko.com/infodetail-3494481.html