私は、シリアル/ UDP/TCPソースから入力データを読み込むシステムを持っています。入力データは、異なるデータタイプ(たとえば、DateTime、double、int、string)のCSVです。例えば、文字列は次のようになります。C#ユーザー定義CSVからPOCOへのマッピング
2012/03/23 12:00:00,1.000,23,information,1.234
私は現在、ユーザーはPOCOのどのプロパティに行くCSVリスト内のどの値を指定することができます(未テスト)コードを持っています。
したがって、上記の例では、私はそうのようなオブジェクト必要があります。このクラスでは今
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を動的に解析する上での他の質問を読んだことがありますが、実行時にはその順序がわかっていますが、ユーザーは注文を定義する必要があります。
これについての議論は次の投稿にあります。 http:// stackoverflowcom/questions/1941392/are-there-any-csv-reader-writer-libraries-in-c – TGH
TextFieldParserクラスは、コードを少し頑強にします。しかし、私は実際にその問題に取り組まれていないマッピング側にもっと興味を持っています。 – Simon
簡単な質問です。あなたはどのように注文を知らないのですか? –