我有一个示例csv文件,如下所示:
Index,Name,Age,Occupation
1,John,23,Driver
2,Jack,28,Painter
3,Alice,26,Accountant
4,Don,19,Student
而且,这是我的csv文件的类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FileHelpers;
namespace FileHelpersTester
{
[DelimitedRecord(",")]
[IgnoreFirst(1)]
public class SpecDataOrder
{
public String Index;
public String Name;
public String Age;
public String Occupation;
}
}
我的主要方法如下:
namespace FileHelpersTester
{
public class Program
{
static void Main(string[] args)
{
String specDataPath = @"C:\sample c# programs\FileHelpersTester\FileHelpersTester\bin\Debug\Sample.csv";
String tester = GetValue(specDataPath, "2", SpecDataOrder.Name); //I expect the value of tester = "Jack"
}
public T GetValue<T>(String csvFilePath, String row, SpecDataOrder col)
{
var engine = new FileHelperEngine<SpecDataOrder>();
var records = engine.ReadFile(csvFilePath);
var dict = new Dictionary<String, SpecDataOrder>();
foreach (var record in records)
{
dict[record.Index] = record;
}
return (T)Convert.ChangeType(dict[row].Index, typeof(T));
}
}
}
我不确定我哪里出错了。这只是我在编写一个处理csv格式的大量数据的更复杂代码之前编写的测试程序。任何帮助都非常感谢。
答案 0 :(得分:0)
此代码存在许多问题。
要解决这四个问题,请尝试使用以下代码:
static void Main(string[] args)
{
String specDataPath = @"C:\sample c# programs\FileHelpersTester\FileHelpersTester\bin\Debug\Sample.csv";
String tester = GetValue<SpecDataOrder>(specDataPath, "2", nameof(SpecDataOrder.Index), nameof(SpecDataOrder.Name)) as string; //I expect the value of tester = "Jack"
}
public static object GetValue<T>(String csvFilePath, object rowIndex, String indexName, String fieldName)
{
var engine = new FileHelperEngine(typeof(T));
var records = engine.ReadFile(csvFilePath);
var memberIndex = new PropertyOrFieldInfo<T>(indexName);
var memberField = new PropertyOrFieldInfo<T>(fieldName);
foreach (T record in records)
{
var indexValue = memberIndex.GetValue(record);
{
if (indexValue.Equals(rowIndex))
{
return memberField.GetValue(record);
}
}
}
return null;
}
在Program.cs中拥有该代码后,您还需要添加以下类。请注意,此类使用反射来获取已传递的未知字段或属性详细信息,以便在有行时获取该字段/属性的值。反射确实会减慢您的代码速度,但有助于实现这种通用性。
public class PropertyOrFieldInfo<T>
{
MemberInfo internalInfo;
PropertyInfo internalProperty;
FieldInfo internalField;
public PropertyOrFieldInfo(string memberName)
{
internalProperty = typeof(T).GetProperty(memberName);
if (internalProperty == null)
{
internalField = typeof(T).GetField(memberName);
if (internalField == null)
throw new MissingMemberException(typeof(T).FullName, memberName);
}
}
public object GetValue(T source)
{
if (internalProperty != null)
return internalProperty.GetValue(source);
else
return internalField.GetValue(source);
}
}
如果您正在计划更大规模的解决方案,请保留用于创建数据表的代码(但添加字典索引代码)并在两个不同的函数中返回单元格值。这样,您就不会为每个单元格查询重新创建表/字典。
请注意,我没有在此处插入代码来检查空值等。您应该添加它以确保不调用null对象上的方法。
答案 1 :(得分:-1)
解决此问题的一种方法如下。但这会改变方法的签名有点得到价值。我不确定您是否可以在生产代码中更改它。
public static T GetValue<T>(String csvFilePath, int row, int col)
{
string line = File.ReadLines(csvFilePath).Skip(row).Take(1).First();
var x = line.Split(',');
return (T)Convert.ChangeType(x[col-1], typeof(T));
}