如何使此扩展方法更通用?

时间:2010-02-05 17:01:33

标签: c# .net generics extension-methods

我正在尝试使以下方法更通用,以便可以为List<T>参数传递任何columnValues。这就是我所拥有的:

public static DataRow NewRow(this DataTable dataTable, List<string> columnValues)
{
    DataRow returnValue = dataTable.NewRow();

    while (columnValues.Count > returnValue.Table.Columns.Count)
    {
        returnValue.Table.Columns.Add();
    }

    returnValue.ItemArray = columnValues.ToArray();
    return returnValue;
}

我可以将其更改为List<object>并在将原始列表传递给方法之前转换原始列表,但我确信有更好的选择: - )

修改

弗兰克的帖子让我重新思考这一点。在大多数情况下,源List<T>将是List<object>,因为列值很可能是不同的类型。

对于我的初次使用List<string>有意义,因为我是从CSV解析创建数据集,这是该点的所有文本。

4 个答案:

答案 0 :(得分:5)

为什么不使用params object[]:

public static DataRow NewRow(this DataTable dataTable, params object[] objects)
{
    DataRow returnValue = dataTable.NewRow();

    while (objects.Length > returnValue.Table.Columns.Count)
    {
        returnValue.Table.Columns.Add();
    }

    returnValue.ItemArray = objects;
    return returnValue;
}

然后你就可以这样称呼它:

myDataTable.NewRow(1,2,"hello");

答案 1 :(得分:4)

你基本上没有运气,因为DataRow的Item数组是一个对象数组,也就是说,最终你只能传入对象列表。

如果您输入列表的通用参数,列表中的所有项目都必须属于该类型,这几乎不可能有用。

话虽如此,为了获得众多不同类型的列,您可以更改扩展方法以接受实例化匿名类型的对象:

table.NewRow(new  { A = "Hello", B = 1, C = DateTime.Now })

有了将匿名类型值转换为字符串的帮助,对象字典by reflection or by a dynamic method它应该是一个非常有用的东西。

答案 2 :(得分:2)

怎么样?
IEnumerable<object>

有关
columnValues.Select(x => x.ToString()).ToArray();

答案 3 :(得分:1)

如何使用闭包来指定如何根据输入类型生成ItemArray

public static DataRow NewRow<T>(this DataTable dataTable, List<T> columnValues, Func<T, string> itemArrayCriteria)
{
    DataRow returnValue = dataTable.NewRow();

    while (columnValues.Count > returnValue.Table.Columns.Count)
    {
        returnValue.Table.Columns.Add();
    }

    returnValue.ItemArray = columnValues.Select(x => itemArrayCriteria(x)).ToArray();
    return returnValue;
}