我有一个从串行/UDP/TCP 源读取输入数据的系统。输入数据只是不同数据类型(例如 DateTime、double、int、string)的 CSV。示例字符串可能是:
2012/03/23 12:00:00,1.000,23,information,1.234
我目前有(未经测试的)代码,允许用户指定 CSV 列表中的哪个值转到 POCO 的哪个属性。
所以在上面的例子中,我会有一个像这样的对象:
public class InputData
{
public DateTime Timestamp{get;set;}
public double Distance{get;set;}
public int Metres{get;set;}
public string Description{get;set;}
public double Height{get;set;}
}
现在在这个课程中,我有一个方法来解析 CSV 字符串并填充属性。此方法还需要“映射”信息,因为无法保证 CSV 数据将以哪种顺序到达 - 由用户定义正确的顺序。
这是我的映射类:
//This general class handles mapping CSV to objects
public class CSVMapping
{
//A dictionary holding Property Names (Key) and CSV indexes (Value)
//0 Based index
public IDictionary<string, int> Mapping { get; set; }
}
现在我的方法 ParseCSV():
//use reflection to parse the CSV survey input
public bool ParseCSV(string pCSV, CSVMapping pMapping)
{
if (pMapping == null) return false;
else
{
Type t = this.GetType();
IList<PropertyInfo> properties = t.GetProperties();
//Split the CSV values
string[] values = pCSV.Split(new char[1] { ',' });
//for each property set its value from the CSV
foreach (PropertyInfo prop in properties)
{
if (pMapping.Mapping.Keys.Contains(prop.Name))
{
if (prop.GetType() == typeof(DateTime))
{
if (pMapping.Mapping[prop.Name] >= 0 && pMapping.Mapping[prop.Name] < values.Length)
{
DateTime tmp;
DateTime.TryParse(values[pMapping.Mapping[prop.Name]], out tmp);
prop.SetValue(this, tmp, null);
}
}
else if (prop.GetType() == typeof(short))
{
if (pMapping.Mapping[prop.Name] >= 0 && pMapping.Mapping[prop.Name] < values.Length)
{
double tmp;
double.TryParse(values[pMapping.Mapping[prop.Name]], out tmp);
prop.SetValue(this, Convert.ToInt16(tmp), null);
}
}
else if (prop.GetType() == typeof(double))
{
if (pMapping.Mapping[prop.Name] >= 0 && pMapping.Mapping[prop.Name] < values.Length)
{
double tmp;
double.TryParse(values[pMapping.Mapping[prop.Name]], out tmp);
prop.SetValue(this, tmp, null);
}
}
else if (prop.GetType() == typeof(string))
{
if (pMapping.Mapping[prop.Name] >= 0 && pMapping.Mapping[prop.Name] < values.Length)
{
prop.SetValue(this, values[pMapping.Mapping[prop.Name]], null);
}
}
}
}
return true;
}
}
现在我的问题是:
我可能有几个类需要此功能。实现一个泛型类或扩展类来为我进行解析是否有益?我的方法是解析 CSV 数据并填充我的对象的好方法吗?还是有更好的方法来做到这一点?
我已经阅读了有关动态解析 CSV 的其他问题,但所有问题都涉及运行时之前已知的顺序,而我要求用户定义顺序。