如何使这个扩展方法更加通用?

6

我正在尝试使下面的方法更加通用,以便任何 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>,并在传递给方法之前将原始列表转换,但我相信有更好的选择 :-)
编辑:Frank的帖子让我重新考虑了这个问题。在大多数情况下,源List<T>将是List<object>,因为列值很可能是不同类型的。
对于我的初始用途,List<string>是有意义的,因为我正在从CSV解析中创建数据集,此时所有文本都是文本。
4个回答

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");

4

很遗憾,因为DataRow的Item Array是一个对象数组,所以最终你只能传递对象列表。

如果你在列表中放置了一个泛型参数,那么列表中的所有项都必须是该类型,这很不可能有用。

话虽如此,为了获得多个具有不同类型的列,你可以更改扩展方法,接受一个对象,然后实例化一个匿名类型:

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

通过使用反射或动态方法将匿名类型值转换为字符串,对象字典应该是相当有用的


你的观点非常好,我之前没有考虑到。在我的初始使用中,List<string> 是有意义的,因为我是从 CSV 解析创建数据集,此时所有内容都是文本。但对于大多数其他用途来说,这并不合适,因为列值很可能是不同类型的。 - Cory Charlton

2

关于什么?

IEnumerable<object>

与...有关

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

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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接