Попытка перебрать записи из CsvHelper выдает ошибку ConfigurationException - PullRequest
0 голосов
/ 17 июня 2019

Я пытаюсь перебрать CSV-файл для вывода на консоль. Я использую CsvHelper и следовал инструкциям к T, но всякий раз, когда я пытаюсь перебрать IEnumerable, полученный из метода GetRecords (), возникает исключение ConfigurationException.

Вот код, который я использую

using (var reader_ans = new StreamReader("scriptlists/prac_iden_ans.csv"))
using (var csv_ans = new CsvReader(reader_ans))
{
    var ans = csv_ans.GetRecords<string>();

    foreach (string item in ans)
    {
        Debug.Log(item);
    }
}

Это странно, потому что это именно то, что есть в документации и на нескольких сайтах.

Появляется ошибка:

ConfigurationException: Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?

Мне было интересно, если это какая-то глупость, которую я пропускаю, потому что я довольно плохо знаком с C #. Я также кодирую это в Unity3D, так что это может быть частью проблемы?

Я также пытался использовать метод .ToList () в самой первой строке, но безрезультатно.


Edit1:

После попытки создания пользовательского класса я столкнулся с другой ошибкой, на этот раз от компилятора, прежде чем я смог даже запустить код.

По сути, в этом фрагменте кода:

foreach (string item in ans)
            {
                Debug.Log(item);
            }

foreach подсвечивается и выдает сообщение об ошибке «Невозможно преобразовать тип« rules.ScriptsList »в« string »». Мой файл называется "Инструкции.cs".

Некоторая дополнительная информация, которая может быть проблемой:

1) Я пишу этот фрагмент кода в IEnumerator, но я не думаю, что это должно быть проблемой, поскольку у меня есть другие строки "foreach". Разве CsvHelper использует определенный код, который не будет работать в IEnumerator?

2) Мои файлы .csv были созданы в Excel и имеют заголовки. На самом деле это просто несколько столбцов «Да» и «Нет». Повлияет ли создание его в Excel и сохранение его в формате .csv (с разделителями-запятыми) на то, как его читает CsvHelper?

3) Имеет ли значение, что класс написан над этой функцией? (Я знаю, что это довольно просто, но я довольно плохо знаком с C # и заметил, что во многих документах класс обычно пишется ниже функции)

Большое вам спасибо за помощь!

Ответы [ 2 ]

1 голос
/ 17 июня 2019

Для вашего обновленного вопроса:

  1. Это была опечатка с моей стороны. Забыл изменить переменную foreach item с string на ScriptsList. Я обновил свой ответ. Ваш фрагмент должен быть:
foreach (ScriptsPath item in ans)
{
    Debug.Log(item);
}
  1. Нет. Там нет никаких различий. Единственное, на что нужно обратить внимание, это то, что иногда .csv форматируется с точкой с запятой ; вместо запятой , в качестве разделителя. Но .csv является одним из самых основных форматов

  2. Нет. Общепринято записывать class, struct и enum в конец файла и ниже класса, если он занимает один и тот же файл / пример. Он является частью синтаксиса C #, и компиляторы C # для не требуют определенного расположения определений типов. Это отличается от кода, который вы пишете в методах сверху вниз, а определения типов следуют более широкой древовидной структуре.

    Поток кода, который вы пишете на C #, является лишь частью полного синтаксиса C #. На мой взгляд, сила в C # заключается в остальном его синтаксисе, с такими вещами, как пространства имен, свойства, методы перечислителя, модификаторы доступности и т. Д.

1 голос
/ 17 июня 2019

Полученное вами сообщение об ошибке указывает на невозможность заполнения данной конфигурации.

Вы хотите дать GetRecords<> класс или структуру, которые будут заполняться значениями из каждой строки в вашем .csv. Возможно, ваш сценарий не выполнен из-за его попытки заполнить строку в тип string и произошел сбой.

Пример решения, если ваш .csv выглядит примерно так:

Ваш prac_iden_ans.csv файл:

Path
C:/example/path/one
C:/example/path/two

Ваш файл сценария .cs C #:

void YourFunction() {

    using (var reader_ans = new StreamReader("scriptlists/prac_iden_ans.csv"))
    using (var csv_ans = new CsvReader(reader_ans))
    {
        var ans = csv_ans.GetRecords<ScriptsList>();

        foreach (ScriptsList item in ans)
        {
            Debug.Log(item.Path);
        }
    }

}

class ScriptsList {
    public string Path { get; set; }
}

Однако, если в вашем файле .csv отсутствует строка заголовка (т. Е. Первая строка, указывающая, что представляет каждый столбец), вы можете настроить CsvReader так, чтобы он не ожидался. Однако тогда вы должны указать CsvReader, какие столбцы сопоставить с какими свойствами по-другому. Одним из способов является IndexAttribute. Пример:

Ваш prac_iden_ans.csv файл:

C:/example/path/one
C:/example/path/two

Ваш файл сценария .cs C #:

void YourFunction() {

    using (var reader_ans = new StreamReader("scriptlists/prac_iden_ans.csv"))
    using (var csv_ans = new CsvReader(reader_ans))
    {
        csv_ans.Configuration.HasHeaderRecord = false;
        var ans = csv_ans.GetRecords<ScriptsList>();

        foreach (ScriptsList item in ans)
        {
            Debug.Log(item.Path);
        }
    }

}

class ScriptsList {
    [Index(0)]
    public string Path { get; set; }
}

Но если вы просто читаете каждую строку в строке строка за строкой, я бы вместо этого рекомендовал просто использовать StreamReader, File.OpenRead или просто File.ReadAllLines. Пример:

Ваш prac_iden_ans.csv файл:

C:/example/path/one
C:/example/path/two

Ваш файл сценария .cs C #:

string[] ans = File.ReadAllLines("scriptlists/prac_iden_ans.csv");

foreach (string item in ans)
{
    Debug.Log(item);
}
...