有没有办法将 IEnumerable<T> 视为参数 T[] 对象?
Is there a way to treat an IEnumerable<T> as a params T[] object?
我想编写 returns Sql 服务器过程结果为 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;
}
熟悉这个问题的朋友可能已经猜到我最后的数据表是这样的:
这些值都被视为一个对象,因此都被插入到第 1 列中。
这里有什么解决方法(如果有)?我在其他帖子中读到 C#6 似乎将 修复 这个问题,除此之外没有找到清晰简洁的解决方案。
如果你有一个 IEnumerable<T>
并且一个方法需要一个 T[]
,只需在你的可枚举上调用 ToArray
。
var fields = resultRecord.GetType().GetProperties().Select(p => p.GetValue(resultRecord).ToString());
resultAsDataTable.Rows.Add(fields.ToArray());
定义 IEnumerable<T>
而不是 T[]
的 params
参数的能力并没有最终进入 C# 6(参见 Eric Lippert's answer about the feature, which links to the announcement of the feature being removed from C# 6). However, even with that theoretical feature, it wouldn't help in this case. That feature would allow the designer of an API (e.g. the person writing DataRowCollection.Add
)以接受 IEnumerable<T>
而不是 T[]
如果他们这样选择(在这种情况下,他们几乎肯定不会,因为这将是一个无声的破坏性变化)。它不允许您将 IEnumerable<T>
传递给需要 T[]
的方法。作为方法的调用者,如果您不使用参数的 params
属性(即传递单个参数而不是集合),那么它只是一个采用数组的 "normal" 方法,并且您负责将参数转换为预期类型。
您实际上可以将数组传递给 params object[]
,因此临时解决方案可能只是:
var fields = resultRecord.GetType().GetProperties()
.Select(p => p.GetValue(resultRecord).ToString())
.ToArray();
resultAsDataTable.Rows.Add(fields);
我想编写 returns Sql 服务器过程结果为 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;
}
熟悉这个问题的朋友可能已经猜到我最后的数据表是这样的:
这些值都被视为一个对象,因此都被插入到第 1 列中。
这里有什么解决方法(如果有)?我在其他帖子中读到 C#6 似乎将 修复 这个问题,除此之外没有找到清晰简洁的解决方案。
如果你有一个 IEnumerable<T>
并且一个方法需要一个 T[]
,只需在你的可枚举上调用 ToArray
。
var fields = resultRecord.GetType().GetProperties().Select(p => p.GetValue(resultRecord).ToString());
resultAsDataTable.Rows.Add(fields.ToArray());
定义 IEnumerable<T>
而不是 T[]
的 params
参数的能力并没有最终进入 C# 6(参见 Eric Lippert's answer about the feature, which links to the announcement of the feature being removed from C# 6). However, even with that theoretical feature, it wouldn't help in this case. That feature would allow the designer of an API (e.g. the person writing DataRowCollection.Add
)以接受 IEnumerable<T>
而不是 T[]
如果他们这样选择(在这种情况下,他们几乎肯定不会,因为这将是一个无声的破坏性变化)。它不允许您将 IEnumerable<T>
传递给需要 T[]
的方法。作为方法的调用者,如果您不使用参数的 params
属性(即传递单个参数而不是集合),那么它只是一个采用数组的 "normal" 方法,并且您负责将参数转换为预期类型。
您实际上可以将数组传递给 params object[]
,因此临时解决方案可能只是:
var fields = resultRecord.GetType().GetProperties()
.Select(p => p.GetValue(resultRecord).ToString())
.ToArray();
resultAsDataTable.Rows.Add(fields);