我正在实现用于向数据填充值的“类型无关”方法。 预期的功能是相当简单 - 调用者传递一个需要填充的列值和DataRow的字符串表示的集合:在C中动态字符串解析#
private void FillDataRow(List<ColumnTypeStringRep> rowInput, DataRow row)
ColumnTypeStringRep结构包含的值,列名的字符串表示,和 - 什么是最重要 - 列数据类型:
private struct ColumnTypeStringRep
{
public string columnName; public Type type; public string stringRep;
public ColumnTypeStrinRep(string columnName, Type type, string stringRep)
{
this.columnName = columnName; this.type = type; this.stringRep = stringRep;
}
}
那么,“类型独立性”是什么?基本上我不关心数据行模式(它总是一些类型化的数据表的一行),只要传递的列名匹配DataRow的列名和列数据类型与DataRow匹配就行了。这个功能需要尽可能的灵活(并且尽可能简单 - 只是不简单)。 这是(几乎):
private void FillDataRow(List<ColumnTypeStrinRep> rowInput, DataRow row)
{
Debug.Assert(rowInput.Count == row.Table.Columns.Count);
foreach (ColumnTypeStrinRep columnInput in rowInput)
{
Debug.Assert(row.Table.Columns.Contains(columnInput.columnName));
Debug.Assert(row.Table.Columns[columnInput.columnName].DataType == columnInput.type);
// --> Now I want something more or less like below (of course the syntax is wrong) :
/*
row[columnInput.columnName] = columnInput.type.Parse(columnInput.stringRep);
*/
// --> definitely not like below (this of course would work) :
/*
switch (columnInput.type.ToString())
{
case "System.String":
row[columnInput.columnName] = columnInput.stringRep;
break;
case "System.Single":
row[columnInput.columnName] = System.Single.Parse(columnInput.stringRep);
break;
case "System.DateTime":
row[columnInput.columnName] = System.DateTime.Parse(columnInput.stringRep);
break;
//...
default:
break;
}
*/
}
}
现在,你可能会看到我的问题 - 我不想使用switch语句。与第一个注释片段一样,这将是完美的,以某种方式使用提供的列类型来调用特定类型的Parse方法,该方法返回由字符串表示形式构造的该类型的对象。 交换机解决方案的工作原理,但它非常不灵活 - 如果将来我将填充不是DataRow,而是一些其他具有可定制类型的“列”的自定义类型(当然,每种类型都需要公开Parse方法从字符串表示构建自己)。
希望你明白我的意思 - 它像“动态解析”类功能。有没有办法在.NET中实现这一点? FillDataRow通话
例子看起来是这样的:
List<ColumnTypeStrinRep> rowInput = new List<ColumnTypeStrinRep>();
rowInput.Add(new ColumnTypeStringRep("colName1", Type.GetType("System.Int32"), "0"));
rowInput.Add(new ColumnTypeStringRep("colName2", Type.GetType("System.Double"), "1,11"));
rowInput.Add(new ColumnTypeStringRep("colName3", Type.GetType("System.Decimal"), "2,22"));
rowInput.Add(new ColumnTypeStringRep("colName4", Type.GetType("System.String"), "test"));
rowInput.Add(new ColumnTypeStringRep("colName5", Type.GetType("System.DateTime"), "2010-01-01"));
rowInput.Add(new ColumnTypeStringRep("colName6", Type.GetType("System.Single"), "3,33"));
TestDataSet.TestTableRow newRow = this.testDataSet.TestTable.NewTestTableRow();
FillDataRow(rowInput, newRow);
this.testDataSet.TestTable.AddTestTableRow(newRow);
this.testDataSet.TestTable.AcceptChanges();
谢谢!
谢谢 - 我会尽快查看。看起来很有希望。我也在考虑“纯粹”的反思 - 对特定类型使用GetMethod(“Parse”),然后通过MethodInfo调用Parse - 我不确定它是否是正确的方式,我无法使其工作。 – garret 2010-02-24 20:28:40
很棒的回答。忘记.NET TypeConverters。 – jrista 2010-02-24 20:29:59
Convert类的附录。您应该能够使用Convert.ChangeType()方法来转换所有内容,而不仅仅是基元。只要你有一个TypeConverter,ChangeType方法应该找到你的类型转换器并且执行转换,只要源和目标类型在某个可用的程序集中某个转换器支持。 – jrista 2010-02-24 20:36:15