Как я могу сделать этот метод расширения более общим? - PullRequest
6 голосов
/ 05 февраля 2010

У меня мозг пердит, я пытаюсь сделать следующий метод более универсальным, чтобы любой 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> и преобразовать исходный список перед передачей его методу, но я уверен, что есть лучший вариант: -)

Edit:

Пост Фрэнка заставил меня переосмыслить это. В большинстве случаев источником List<T> будет List<object>, поскольку значения столбцов, скорее всего, будут разных типов.

Для моего первоначального использования List<string> имел смысл, потому что я создавал набор данных из синтаксического анализа CSV, который представляет собой весь текст на этом этапе.

Ответы [ 4 ]

5 голосов
/ 05 февраля 2010

Почему бы просто не использовать 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 голосов
/ 05 февраля 2010

Вам в основном не повезло, потому что массив элементов DataRow представляет собой массив объектов, то есть, в конечном счете, вы можете передать только список объектов.

Если вы введете общий параметр списка, все элементы списка должны быть этого типа, что вряд ли будет полезным.

Сказав, что для того, чтобы получить множество столбцов, все с разными типами, вы можете изменить свой метод расширения, чтобы принимать объект, в который вы создаете экземпляр анонимного типа:

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

С помощью преобразования значений анонимного типа в строку, словарь объектов либо с помощью отражения, либо динамическим методом это должно быть довольно полезным делом.

2 голосов
/ 05 февраля 2010

А как же

IEnumerable<object>

в связи с

columnValues.Select(x => x.ToString()).ToArray();
1 голос
/ 04 марта 2010

Как насчет использования замыкания, чтобы указать, как генерировать 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;
}
...