"N/A" 作为 int 字段的空值
"N/A" as null value of int field
我必须处理(即我无法控制)csv 文件,其中 "N/A" 是 "should" 为整数的字段的可能值,我一直在努力弄清楚如何以"roll my own" TypeConversion class 来处理这个,但是没能找到例子。 Josh 的示例页面在这个特定区域明显缺失,我能找到的最接近的 Whosebug 问题是 this one 从 2013 年开始。
然后我找到了对 NullValuesAttribute 的引用,这似乎正是我所需要的,但后来不知道如何使用它。 VisualStudio 的 Intellisense 也无济于事。 :)
理想情况下,我希望 "N/A"s 转换为 0(零)。有人可以帮忙吗?
在人们告诉我之前 "Well, it's obvious..." 我应该说这是我的第一个(从字面上看,除了教程之外)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(因为似乎没有 "BooleanValues" 方法的 Int32 等价物。
不幸的是,这仍然引发异常:
CsvHelper.TypeConversion.TypeConverterException: 'The conversion cannot be performed.
Text: 'N/A'
MemberType:
TypeConverter: 'CsvHelper.TypeConversion.Int32Converter''
所以,看起来我将不得不扩展 Int32Converter。是吗?
虽然这不是最优雅的解决方案,但至少目前对我有用:
从上面的代码中,删除 JobMap
class。也不需要 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")
};
您可以像这样定义自定义类型转换器:
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());
我必须处理(即我无法控制)csv 文件,其中 "N/A" 是 "should" 为整数的字段的可能值,我一直在努力弄清楚如何以"roll my own" TypeConversion class 来处理这个,但是没能找到例子。 Josh 的示例页面在这个特定区域明显缺失,我能找到的最接近的 Whosebug 问题是 this one 从 2013 年开始。
然后我找到了对 NullValuesAttribute 的引用,这似乎正是我所需要的,但后来不知道如何使用它。 VisualStudio 的 Intellisense 也无济于事。 :)
理想情况下,我希望 "N/A"s 转换为 0(零)。有人可以帮忙吗?
在人们告诉我之前 "Well, it's obvious..." 我应该说这是我的第一个(从字面上看,除了教程之外)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(因为似乎没有 "BooleanValues" 方法的 Int32 等价物。
不幸的是,这仍然引发异常:
CsvHelper.TypeConversion.TypeConverterException: 'The conversion cannot be performed.
Text: 'N/A'
MemberType:
TypeConverter: 'CsvHelper.TypeConversion.Int32Converter''
所以,看起来我将不得不扩展 Int32Converter。是吗?
虽然这不是最优雅的解决方案,但至少目前对我有用:
从上面的代码中,删除 JobMap
class。也不需要 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")
};
您可以像这样定义自定义类型转换器:
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());