【问题标题】:C# foreach loop not executingC# foreach 循环未执行
【发布时间】:2020-06-28 00:59:46
【问题描述】:

我有以下仅执行第一个 foreach 循环的代码。当我在 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);
        }

【问题讨论】:

    标签: c# foreach


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      有没有办法在不使用 IEnumerable 的情况下循环 foreach 循环(就像一个 for 循环,虽然我还没有弄清楚如何 这样做)。

      试试这个来获取枚举数:


      选项 1 与 Enumerator:

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

      带有List的选项2:

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

      参考文档: 建议,我更喜欢一次性获取对象列表,更容易,更好。基于参考。来自CsvHelper Page

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

      将 CSV 行转换为可在每个 可枚举的迭代。每个枚举都会水合给定的 记录,但只有映射的成员。如果您提供了地图但没有 映射其中一位成员,该成员将 ---- > 不会与 当前行的数据。 ----> 小心。您调用的任何方法 强制评估 IEnumerable 的投影,例如 ToList(),你会得到一个所有记录都相同的列表 您提供的实例与 CSV 中的最后一条记录水合 文件。

      【讨论】:

        【解决方案3】:

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

        using System.Linq;
        

        并更改此代码:

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

        到此代码:

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

        祝你好运!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-29
          • 1970-01-01
          • 1970-01-01
          • 2018-05-28
          • 2021-01-27
          相关资源
          最近更新 更多