【问题标题】:"N/A" as null value of int field"N/A" 作为 int 字段的空值
【发布时间】:2019-03-21 01:51:20
【问题描述】:

我必须使用(即我无法控制)csv 文件,其中“N/A”是“应该”为整数的字段的可能值,我一直在试图弄清楚如何“滚动我的自己的”TypeConversion 类来处理这个,但一直找不到例子。 Josh 的示例页面在这个特定区域明显缺乏,我能找到的最接近的 stackoverflow 问题是 2013 年的this one

然后我找到了对 NullValuesAttribute 的引用,这似乎正是我所需要的,但后来不知道如何使用它。 VisualStudio 的 Intellisense 也无济于事。 :)

理想情况下,我希望将“N/A”转换为 0(零)。有人可以帮忙吗?

在人们告诉我“嗯,这很明显......”之前,我应该说这是我的第一个(字面意思是,除了教程之外)C# 程序,而且还有一个时间因素 - 或者我很乐意在我的拥有。

[更新:在CsvHelper Parsing boolean from String 尝试了顶级适配解决方案]

所以,以解决上述问题为出发点,我这样做了:

static void Main()
{
    var rows = new List<Job>();

    using (var reader = new StreamReader("mydatafile.csv")
    using (var csv = new CsvReader(reader))
    {
         csv.Configuration.RegisterClassMap<JobMap>();
         while (csv.Read())
         {
              var record = new Job
              {
                   JobId = csv.GetField<int>("Job ID"),
                   ItemCount = csv.GetField<int>("Item Count")
              };
              rows.Add(record);
         }
    }
}

public class Job
{
    public int JobId { get; set; }
    public int ItemCount { get; set; }
}

public sealed class JobMap : ClassMap<Job>
{
    Map(m => m.JobId);
    Map(m => m.ItemCount).TypeConverterOption.NullValues("N/A");
}

我的想法是指定 NullValues 会使 TypeConverter 将“N/A”转换为 null(因为似乎没有 Int32 等效于“BooleanValues”方法。

不幸的是,这仍然引发了异常:

CsvHelper.TypeConversion.TypeConverterException: 'The conversion cannot be performed.
Text: 'N/A'
MemberType: 
TypeConverter: 'CsvHelper.TypeConversion.Int32Converter''

所以,看来我将不得不扩展 Int32Converter。是吗?

【问题讨论】:

  • 请注意tagging help 中标题为“我应该在标题中使用标签吗?”的部分
  • This seems like it might be a good place to start。我很欣赏它适用于布尔值而不是整数,但它应该很容易适应。
  • 对不起@John,我没有尝试在标题中使用标签。先写了标题,然后加了标签,没有回去编辑。 :)
  • 不用担心 :) 其他问题对您有帮助吗?
  • 我现在正在尝试。待机...

标签: c# csvhelper


【解决方案1】:

您可以像这样定义自定义类型转换器:

using CsvHelper;
using CsvHelper.TypeConversion;
using CsvHelper.Configuration;

public class CustomInt32Converter: Int32Converter {
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        if (text == "N/A") return 0;
        return base.ConvertFromString(text, row, memberMapData);
    }
}

然后你可以用这一行注册你的转换器:

csv.Configuration.TypeConverterCache.AddConverter<int>(new CustomInt32Converter());

【讨论】:

  • 太棒了!谢谢,元骑士!
【解决方案2】:

虽然不是最优雅的解决方案,但至少目前对我有用:

从上面的代码中,删除JobMap 类。也不需要csv.Configuration... 行。

创建新函数

static int HandleNA (CsvReader csv, string field)
{
    return (csv.GetField<string>(field) == "N/A") ? 0 : csv.GetField<int>(field);
}

并在

中使用它
var record = new Job
{
    JobId = csv.GetField<int>("Job ID"),
    ItemCount = HandleNA(csv, "Item Count")
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-15
    • 2018-02-16
    • 2023-03-06
    • 2021-01-07
    • 1970-01-01
    • 2021-05-09
    • 2023-03-03
    • 2017-01-21
    相关资源
    最近更新 更多