【问题标题】:Using csvHelper to read cell content into List or Array使用 csvHelper 将单元格内容读入列表或数组
【发布时间】:2020-04-01 08:05:50
【问题描述】:

我有一个 csv 文件类型:

name,numbersA,numbersB
Bob,"1,2,3,4","6,7,8,9"
Brabra,"9,3","4,8,5,7,2"

所以整数数组由“”之间的数字给出。

我想把它映射到下面的类

    public class Names
    {
        [Name("name")]
        public string Name { get; set; }

        [Name("numbersA")]
        public List<int> NumbersA{ get; set; }

        [Name("numbersB")]
        public List<int> NumbersB{ get; set; }

    }

我并不特别介意 NumbersA/B 是 int[] 还是 List 类型。到目前为止,我设法通过将 NumbersA/B 的类型指定为字符串来读取数据,并且工作正常(我得到了“”之间的字符串)。这可以在 csvHelper 中自动完成,还是我以后必须自己解析字符串。

void Main()
{
    using (var reader = new StreamReader("path\\to\\file.csv"))
    using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
    {
        var records = csv.GetRecords<Names>();
        List<Names> NameList = records.ToList();
    }
}

非常感谢任何帮助。

解决方案

感谢@Oguz Ozgul(见下文)。我做了一些小改动。


public class Names
{
    [Name("name")]
    public string Name { get; set; }

    [Name("numbersA")]
    [TypeConverter(typeof(ToIntArrayConverter))]
    public List<int> NumbersA{ get; set; }

    [Name("numbersB")]
    [TypeConverter(typeof(ToIntArrayConverter))]
    public List<int> NumbersB{ get; set; }

}

public class ToIntArrayConverter : TypeConverter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        if (text == "") return new List<int>();
        string[] allElements = text.Split(',');
        int[] elementsAsInteger = allElements.Select(s => int.Parse(s)).ToArray();
        return new List<int>(elementsAsInteger);
    }

    public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
    {
        return string.Join(",", ((List<int>)value).ToArray());
    }
}

【问题讨论】:

    标签: c# csvhelper


    【解决方案1】:

    您可以实现自定义类型转换器并在转换期间(双向)为您的两个属性使用它。

    TypeConverter 类在命名空间 CsvHelper.TypeConversion

    TypeConverterAttribute 位于命名空间 CsvHelper.Configuration.Attributes

        public class ToIntArrayConverter : TypeConverter
        {
            public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
            {
                string[] allElements = text.Split(',');
                int[] elementsAsInteger = allElements.Select(s => int.Parse(s)).ToArray();
                return new List<int>(elementsAsInteger);
            }
    
            public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
            {
                return string.Join(',', ((List<int>)value).ToArray());
            }
        }
    

    要使用此转换器,只需在属性顶部添加以下 TypeConverterAttribute 注释:

        public class Names
        {
            [Name("name")]
            public string Name { get; set; }
    
            [Name("numbersA")]
            [TypeConverter(typeof(ToIntArrayConverter))]
            public List<int> NumbersA { get; set; }
    
            [Name("numbersB")]
            [TypeConverter(typeof(ToIntArrayConverter))]
            public List<int> NumbersB { get; set; }
        }
    

    【讨论】:

    • 完成,抱歉我是新手 :)
    • 我得到 Cannot Resolve Symbol ToIntArrayConverter 我正在使用这些导入:using CsvHelper.Configuration.Attributes; using CsvHelper.TypeConversion; using CsvHelper;
    • 嗨@tblev,答案中实现了“ToIntArrayConverter”类。你需要从上面复制这个类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    相关资源
    最近更新 更多