Pregunta

Todavía soy nuevo en C # y he estado luchando con varias cuestiones sobre matrices. Tengo una gran variedad de objetos de metadatos (pares de nombre y valor) y me gustaría saber cómo crear sólo el número de objetos "InputProperty" que realmente necesita. En este bucle he fijado arbitrariamente el número de elementos a 20 y trato de rescatar a cuando la entrada se vuelve nula, pero el servicio web en el extremo receptor de este no le gusta ningún elemento nulo que se le pasan:

private Update BuildMetaData(MetaData[] nvPairs)
{
    Update update = new Update();
    InputProperty[] ip = new InputProperty[20];  // how to make this "dynamic"
    int i;
    for (i = 0; i < nvPairs.Length; i++)
    {
        if (nvPairs[i] == null) break;
        ip[i] = new InputProperty();
        ip[i].Name = "udf:" + nvPairs[i].Name;
        ip[i].Val = nvPairs[i].Value;
    }
    update.Items = ip;
    return update;
}

En resumen, decir que sólo tengo 3 pares NameValue en la matriz de entrada por encima? En lugar de asignar los 20 elementos de la matriz llamada IP, ¿cómo se puede codificar esta manera ip es sólo tan grande como lo que debe ser. El objeto de actualización se hace pasar a través de otro servicio web así serialización es importante (es decir, no puedo usar NameValueCollection, etc.).

p.s. Es la única forma durante el seguimiento en una pregunta publicada a través de la instalación de "agregar comentarios"?

¿Fue útil?

Solución

Si no desea utilizar un List, ArrayList, u otra colección dinámica de tamaño y luego convertir a un array (que es el método que recomiendo, por cierto), entonces usted tendrá que asignar el matriz a su máximo tamaño posible, hacer un seguimiento de cuántos artículos que usted pone en él, y luego crear una nueva matriz con sólo esos elementos en él:

private Update BuildMetaData(MetaData[] nvPairs)
{
    Update update = new Update();
    InputProperty[] ip = new InputProperty[20];  // how to make this "dynamic"
    int i;
    for (i = 0; i < nvPairs.Length; i++)
    {
        if (nvPairs[i] == null) break;
        ip[i] = new InputProperty(); 
        ip[i].Name = "udf:" + nvPairs[i].Name;
        ip[i].Val = nvPairs[i].Value;
    }
    if (i < nvPairs.Length)
    {
        // Create new, smaller, array to hold the items we processed.
        update.Items = new InputProperty[i];
        Array.Copy(ip, update.Items, i);
    }
    else
    {
        update.Items = ip;
    }
    return update;
}

Un método alternativo sería asignar siempre update.Items = ip; y luego cambiar el tamaño si es necesario:

update.Items = ip;
if (i < nvPairs.Length)
{
    Array.Resize(update.Items, i);
}

Es menos código, pero probablemente va a terminar haciendo la misma cantidad de trabajo (es decir, la creación de una nueva matriz y la copia de los elementos antiguos).

Otros consejos

InputProperty[] ip = new InputProperty[nvPairs.Length]; 

O bien, puede utilizar una lista de este modo:

List<InputProperty> list = new List<InputProperty>();
InputProperty ip = new (..);
list.Add(ip);
update.items = list.ToArray();

Otra cosa que me gustaría señalar, en C # se puede delcare su uso variable entero en un bucle for derecha dentro del bucle:

for(int i = 0; i<nvPairs.Length;i++
{
.
.
}

Y sólo porque estoy en el estado de ánimo, he aquí una forma más limpia de hacer este método IMO:

private Update BuildMetaData(MetaData[] nvPairs)
{
        Update update = new Update();
        var ip = new List<InputProperty>();

        foreach(var nvPair in nvPairs)
        {
            if (nvPair == null) break;
            var inputProp = new InputProperty
            {
               Name = "udf:" + nvPair.Name,
               Val = nvPair.Value
            };
            ip.Add(inputProp);
        }
        update.Items = ip.ToArray();
        return update;
}

La dosis se necesita ser un array? Si utiliza un ArrayList o uno de los otros objetos disponibles en C #, que no tendrá esta limitación hasta el contenido con. Tabla hash, IDictionnary, IList, etc .. todo permite una serie de elementos dinámicos.

Utilice esta:

 Array.Resize(ref myArr, myArr.Length + 5);

Se puede utilizar la Lista dentro del método y transformarla en una matriz al final. Pero creo que si hablamos de un valor máximo de 20, su código es más rápido.

    private Update BuildMetaData(MetaData[] nvPairs)
    {
        Update update = new Update();
        List<InputProperty> ip = new List<InputProperty>();
        for (int i = 0; i < nvPairs.Length; i++)
        {
            if (nvPairs[i] == null) break;
            ip[i] = new InputProperty();
            ip[i].Name = "udf:" + nvPairs[i].Name;
            ip[i].Val = nvPairs[i].Value;
        }
        update.Items = ip.ToArray();
        return update;
    }

O en C # 3.0 utilizando System.Linq puede saltarse la lista intermedia:

private Update BuildMetaData(MetaData[] nvPairs)
{
        Update update = new Update();
        var ip = from nv in nvPairs
                 select new InputProperty()
                 {
                     Name = "udf:" + nv.Name,
                     Val = nv.Value
                 };
        update.Items = ip.ToArray();
        return update;
}

Uso Array.CreateInstance para crear una matriz dinámica.

    private Update BuildMetaData(MetaData[] nvPairs)
    {
        Update update = new Update();
        InputProperty[] ip = Array.CreateInstance(typeof(InputProperty), nvPairs.Count()) as InputProperty[];
        int i;
        for (i = 0; i < nvPairs.Length; i++)
        {
            if (nvPairs[i] == null) break;
            ip[i] = new InputProperty();
            ip[i].Name = "udf:" + nvPairs[i].Name;
            ip[i].Val = nvPairs[i].Value;
        }
        update.Items = ip;
        return update;
    }

Típicamente, las matrices requieren constantes para inicializar su tamaño. Usted podría barrer sobre nvPairs vez para obtener la longitud, a continuación, "dinámica" crear una matriz usando una variable para la longitud de esta manera.

InputProperty[] ip = (InputProperty[])Array.CreateInstance(typeof(InputProperty), length);

Yo no lo recomendaría, sin embargo. Sólo se adhieren a la

List<InputProperty> ip = ...
...
update.Items = ip.ToArray();

solución. No es que mucho menos eficiente, y mucho mejor mirando.

Puede crear una matriz dinámica de esta manera:

 static void Main()
    {
        // Create a string array 2 elements in length:
        int arrayLength = 2;
        Array dynamicArray = Array.CreateInstance(typeof(int), arrayLength);
        dynamicArray.SetValue(234, 0);                              //  → a[0] = 234;
        dynamicArray.SetValue(444, 1);                              //  → a[1] = 444;
        int number = (int)dynamicArray.GetValue(0);                      //  → number = a[0];


        int[] cSharpArray = (int[])dynamicArray;
        int s2 = cSharpArray[0];

    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top