【发布时间】:2012-04-07 17:01:59
【问题描述】:
我有一个从串行/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 的其他问题,但都处理在运行前已知的顺序,而我要求用户定义顺序。
【问题讨论】:
-
在下面的帖子stackoverflow.com/questions/1941392/…中有关于这个的讨论
-
TextFieldParser 类将使我的代码更加健壮,谢谢。但是,我对所提出的映射方面更感兴趣,而该问题并未真正解决。
-
只是一个简单的问题。你怎么不知道顺序?
-
我知道什么数据会下来,但取决于哪个客户和他们向我们发送数据的方式,决定了顺序。 ClientA 可能先发送日期,ClientB 可能发送距离。这就是为什么我的应用程序的用户需要通过对话框指定映射。