繁体   English   中英

C# foreach 循环未执行

[英]C# foreach loop not executing

我有以下仅执行第一个 foreach 循环的代码。 当我 go 在 Visual Studio 中进入逐步模式时,程序只会跳过每个后续的 foreach 循环。 为什么会发生这种情况,是否有解决方法? 有没有办法在不使用 foreach 循环的情况下循环通过 IEnumerable<> (如 for 循环,虽然我还没有弄清楚如何做到这一点)。

using CsvHelper;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;

...

    public class State
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Pop { get; set; }
        public string Ab { get; set; }
        public int Reps { get; set; }
        public double standardQuota { get; set; }
        public int lowerQuota { get; set; }
        public int upperQuota { get; set; }
    }

...

        static void currentRule(int num)
        {
            IEnumerable<State> records = null;
            int size = 0;
            Console.WriteLine("Please enter a size for the house, greater than the number of states. Current is 435. select 1 for wyoming rule or 2 for cube root.");
            string s = Console.ReadLine();
            size = Int32.Parse(s);
            if (num == 1)
            {
                string path = "C:/.../pop50.csv";
                using (var reader = new StreamReader(path))
                using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
                {
                    records = csv.GetRecords<State>();
                    int total = 0;
                    foreach (var state in records)
                    {
                        total += state.Pop;
                    }
                    var standardDivisor = total / size;
                    foreach (var state in records)
                    {
                        state.standardQuota = state.Pop / standardDivisor;
                        state.lowerQuota = (int)Math.Floor(state.standardQuota);
                        state.upperQuota = (int)Math.Ceiling(state.standardQuota);
                        state.Reps = 1;
                        size -= 1;
                    }
                    while (size > 0)
                    {
                        double max = 0;
                        double maxIndex = 0;
                        int i = -1;
                        foreach (var state in records)
                        {
                            i++;
                            var numSeats = state.Reps;
                            var div = state.Pop / Math.Sqrt(size * (size + 1));
                            if (div > max)
                            {
                                max = div;
                                maxIndex = i;
                            }
                        }
                        foreach (var state in records)
                        {
                            if (state.Id == maxIndex)
                            {
                                state.Reps++;
                                size--;
                            }
                        }
                            
                    }
                }
            }
            print(records);
        }

GetRecords返回一个有状态的IEnumerable ,同时产生一条记录。 这里的操作词是有状态的——一旦你消费了一条记录(例如,通过使用foreach循环对其进行迭代),它就消失了。

您可以在这里采取一些方法:

  1. 将所有内容折叠到一个foreach循环中,而不是执行逻辑的不同部分的三个不同的循环。
  2. 每次需要遍历记录时调用GetRecords 请注意,这将重新读取文件,因此您将执行三倍的 I/O。
  3. 将可迭代对象转换为List (例如,通过使用 Linq 的ToList() ),然后在需要时对其进行迭代。 请注意,这意味着您将在 memory 中保存整个文件的内容,而不是其中的一小部分。

有没有办法在不使用 foreach 循环的情况下循环通过 IEnumerable<> (如 for 循环,虽然我还没有弄清楚如何做到这一点)。

试试这个来获取枚举器:


带有Enumerator的选项 1:

using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{        
 var records = csv.GetRecords<State>();
 var enumerator = records.GetEnumerator();
 while(enumerator.MoveNext())
 {
    var currItemEn = enumerator.Current;            
 }
}

选项 2 与List

// or if you want a list, save this list and reuse it!
records = csv.GetRecords<State>().ToList<State>();

参考文档:建议,我更喜欢一次性获得 object 列表,更简单,更好。 基于参考。 来自CsvHelper 页面

看起来您有多个循环导致reuse the Enumerable ..

将 CSV 行转换为 class object ,在可枚举的每次迭代中重复使用。 每个枚举都会水合给定的记录,但只有映射的成员。 如果您提供了 map 并且没有 map 成员之一,则该成员将 ---- > 不会使用当前行的数据进行补充。 ----> 小心。 您在投影上调用的任何强制评估 IEnumerable 的方法,例如 ToList(),您将获得一个列表,其中所有记录都是您提供的与 CSV 文件中的最后一条记录水合的相同实例

回答你问题的第二部分。 你可以加:

using System.Linq;

并更改此代码:

foreach(var state in records)
{
   total += state.Pop;
 }

对此代码:

int total = records.Sum(X=> state.Pop);

祝你好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM