2008-11-13 35 views
7

Quiero construir matriz de dos dimensional de cadenas, donde longitud de una dimension es 2. Al igual que en este¿Hay alguna manera de definir una lista <> de dos elementos de matriz de cadenas?

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

Haciendo

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

me da

string[][] 

pero no

string[,] 

matriz.

Sólo por curiosidad, ¿hay algún truco para construir dinámicamente

string[,] 

gama de alguna manera?

Respuesta

4

Bueno , podría razonablemente escribir fácilmente un método de extensión para hacerlo. Algo como esto (solo probado muy levemente):

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

Es una lástima que el código anterior use T [] como el tipo de elemento. Debido a la invarianza genérica, actualmente no puedo hacer que la fuente IEnumerable<IEnumerable<T>> sea agradable. Una alternativa podría ser la introducción de un nuevo tipo de parámetro con una restricción:

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

Algo peludo, pero debería funcionar. (Obviamente, la implementación también necesita algunos cambios, pero el principio básico es el mismo.)

+0

muy agradable! Todavía estoy interesado si es posible definir List <> de alguna manera para forzarlo a aceptar solo arreglos de cadenas de dos elementos? –

+0

No hay forma de hacerlo en tiempo de compilación, o con List sí mismo. Hay otra clase (no recuerdo el nombre en este momento) que le permitirá validar las entradas a medida que se agregan, pero eso es solo en el momento de la ejecución. –

0

Esto no es posible con un List<string[]>, ya que el tipo string[,] es diferente de string[].

2

La única manera de hacerlo sería implementar usted mismo la función ToArray(). Puede implementarlo dentro de su propia colección (es decir, StringTupleCollection). Esto podría funcionar igual que ArrayList (es decir, la matriz interna aumenta de tamaño según sea necesario).

Sin embargo no estoy seguro de la ventaja de [x,2] sobre [x][2] (o incluso List<string[2]> sería lo suficientemente importantes como para justificar el esfuerzo

También podría escribir un StringTupple clase como:.

public class StringTupple : KeyValuePair<string, string> 
{ 
} 
17

Puede hacer esto.

List<KeyValuePair<string, string>> 

La idea es que el par de valores clave imitaría la matriz de cadenas que ha replicado.

0

KeyValuePair no funcionó para mí cuando tuve que recuperar los valores de las casillas de verificación en el controlador como mi modelo. La lista de Roles era nula.

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

La estructura KeyValuePair no tiene un constructor sin parámetros por defecto y no puede ser instanciada por el aglutinante modelo. Recomiendo una clase de modelo personalizado para su vista que tenga solo esas propiedades.ASP.NET MVC 3 binding user control of type KeyValuePair to ViewModel

me encontré con una implementación de un CheckBoxList sin el uso de ayuda HTML en el siguiente enlace CheckboxList in MVC3.0

Cuestiones relacionadas