Vev*_*rke 1 c# parameters system.reflection
我想编写将 Sql Server 过程结果作为DataTable对象返回的通用代码。DataTable.Rows.Add()然后我编写了下面的代码,但是,我偶然发现了期望参数的问题params object[],而我必须传递的是IEnumerable<string>.
public static DataTable GetProcedureResults(int id)
{
return GetQueryResultAsDataTable<MyProcedure_Result>(_sqlServerDB.MyProcedure(id));
}
private static DataTable GetQueryResultAsDataTable<T>(ObjectResult<T> objectResult)
{
DataTable resultAsDataTable = new DataTable("Result");
var columns = typeof(T).GetProperties();
foreach (var column in columns)
{
resultAsDataTable.Columns.Add(column.Name, typeof(string));
}
foreach (var resultRecord in objectResult)
{
var fields = resultRecord.GetType().GetProperties().Select(p => p.GetValue(resultRecord).ToString());
resultAsDataTable.Rows.Add(fields);
}
return resultAsDataTable;
}
Run Code Online (Sandbox Code Playgroud)
对于熟悉这个问题的人来说,你可能已经猜到我最后的数据表是这样的:
这些值都被视为单个对象,因此都被插入到第一列中。
如果有的话,这里的解决方法是什么?我在其他帖子中读到,似乎 C#6 会解决这个问题,除此之外没有找到清晰简洁的解决方案。
如果你有一个IEnumerable<T>并且一个方法需要一个T[],只需调用ToArray你的枚举即可。
var fields = resultRecord.GetType().GetProperties().Select(p => p.GetValue(resultRecord).ToString());
resultAsDataTable.Rows.Add(fields.ToArray());
Run Code Online (Sandbox Code Playgroud)
params定义而不是参数的能力IEnumerable<T>最终并T[]没有进入 C# 6(请参阅Eric Lippert 关于该功能的回答,其中链接到从 C# 6 中删除该功能的公告)。然而,即使有这个理论特征,在这种情况下也无济于事。该功能将允许 API 的设计者(例如编写代码的人DataRowCollection.Add)接受IEnumerable<T>,而不是T[]他们自己选择(在这种情况下,他们几乎肯定不会,因为这将是一个无声的重大更改)。它不允许您将 an 传递IEnumerable<T>给需要 a 的方法T[]。作为方法的调用者,如果您没有利用params参数的属性(即传递单个参数而不是集合),那么它只是一个采用数组的“普通”方法,并且您负责转换您对预期类型的参数。