Есть ли способ определить список <> из двух элементов массива строк? - PullRequest
7 голосов
/ 13 ноября 2008

Я хочу построить двумерный массив строк, где длина одного измерения равна 2. Аналогично этому

string[,] array = new string[,]
{
    {"a", "b"},
    {"c", "d"},
    {"e", "f"},
    {"g", "h"}
}

Doing

List<string[]> list = new List<string[]>();

list.Add(new string[2] {"a", "b"});
list.Add(new string[2] {"c", "d"});
list.Add(new string[2] {"e", "f"});
list.Add(new string[2] {"g", "h"});

list.ToArray();

дает мне

string[][]

но не

string[,] 

массив.

Просто любопытно, есть ли какая-то хитрость для динамического построения

string[,] 

массив как-нибудь?

Ответы [ 5 ]

18 голосов
/ 20 мая 2012

Вы можете сделать это.

List<KeyValuePair<string, string>>

Идея в том, что пара ключ-значение будет имитировать массив строк, которые вы реплицировали.

4 голосов
/ 13 ноября 2008

Ну, вы могли бы достаточно легко написать метод расширения для этого. Примерно так (только слегка проверено):

public static T[,] ToRectangularArray<T>(this IEnumerable<T[]> source)
{
    if (!source.Any())
    {
        return new T[0,0];
    }

    int width = source.First().Length;
    if (source.Any(array => array.Length != width))
    {
         throw new ArgumentException("All elements must have the same length");
    }

    T[,] ret = new T[source.Count(), width];
    int row = 0;
    foreach (T[] array in source)
    {
       for (int col=0; col < width; col++)
       {
           ret[row, col] = array[col];
       }
       row++;
    }
    return ret;
}

Немного обидно, что в приведенном выше коде в качестве типа элемента используется T []. Из-за общей инвариантности я не могу сейчас сделать источник IEnumerable<IEnumerable<T>>, что было бы неплохо. Альтернативой может быть введение нового параметра типа с ограничением:

public static T[,] ToRectangularArray<T,U>(this IEnumerable<U> source)
    where U : IEnumerable<T>

Немного волосатый, но это должно сработать. (Очевидно, что реализация тоже нуждается в некоторых изменениях, но основной принцип тот же.)

2 голосов
/ 13 ноября 2008

Единственный способ сделать это - реализовать функцию ToArray() самостоятельно. Вы могли бы реализовать это в своей собственной коллекции (т.е. StringTupleCollection). Это может работать так же, как ArrayList (т. Е. Внутренний массив увеличивается по мере необходимости).

Однако я не уверен, что преимущество [x,2] над [x][2] (или даже List<string[2]> будет достаточно значительным, чтобы оправдать усилия.

Вы также можете написать StringTupple класс как:

public class StringTupple : KeyValuePair<string, string>
{
}
0 голосов
/ 06 сентября 2012

KeyValuePair не работал для меня, когда мне приходилось получать значения флажков на контроллере в качестве модели. Список ролей был нулевым.

foreach (KeyValuePair<string, bool> Role in model.Roles){...}

Структура KeyValuePair не имеет конструктора по умолчанию без параметров и не может быть реализована механизмом связывания модели. Я рекомендую для вашей модели пользовательский класс модели, который имеет только эти свойства. ASP.NET MVC 3 привязывает пользовательский элемент управления типа KeyValuePair к ViewModel

Я нашел реализацию списка флажков без использования помощника html по следующей ссылке CheckboxList в MVC3.0

0 голосов
/ 13 ноября 2008

Это невозможно с List<string[]>, так как тип string[,] отличается от string[].

...