Domanda

Sono ancora nuovo per C # e sono stato alle prese con vari problemi su array. Ho un array di oggetti di metadati (coppie di valori nome) e vorrei sapere come creare solo il numero di oggetti "InputProperty" che ho veramente bisogno. In questo ciclo ho fissato arbitrariamente il numero di elementi a 20 e cerco di tirare fuori dai guai quando la voce diventa nulla, ma il servizio Web sul lato di ricezione di questo non piace elementi NULL passata ad esso:

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

In sintesi, dire ho solo 3 paia NameValue nell'array di ingresso sopra? Invece di allocare 20 elementi per la matrice chiamata IP, come può codificare questo modo ip è solo grande come deve essere. L'oggetto aggiornamento viene passato attraverso un altro webservice così serializzazione è importante (cioè non posso usare NameValueCollection, ecc).

P.S. È l'unico modo per follow-up su una questione Postato attraverso l'impianto "aggiungere commenti"?

È stato utile?

Soluzione

Se non si desidera utilizzare un List, ArrayList, o da un'altra raccolta in modo dinamico-size e poi convertire in una matrice (che è il metodo che vi consiglio, tra l'altro), allora si dovrà allocare la matrice per la sua massima dimensione possibile, tenere traccia di quanti elementi si mette in esso, e quindi creare un nuovo array con solo gli elementi in essa contenuti:

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 metodo alternativo consiste nell'assegnare sempre update.Items = ip; e quindi ridimensionare se necessario:

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

E 'meno codice, ma è probabile che finiscono per fare la stessa quantità di lavoro (vale a dire la creazione di un nuovo array e copiando i vecchi oggetti).

Altri suggerimenti

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

In alternativa, è possibile utilizzare un elenco in questo modo:

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

Un'altra cosa che vorrei sottolineare, in C # è possibile delcare l'utilizzo variabile int in un ciclo for destra all'interno del ciclo:

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

E solo perché sono in vena, ecco un modo più pulito per fare questo metodo di 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;
}

non c'è bisogno di essere un array? Se si utilizza un ArrayList o di uno degli altri oggetti disponibili in C #, non avrete questa limitazione ai contenuti con. Tabella hash, IDictionnary, IList, ecc .. tutto permette una serie dinamica di elementi.

Utilizzare questa:

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

È possibile utilizzare List all'interno del metodo e trasformarlo in un array alla fine. Ma penso che se si parla di un massimo valore di 20, il codice è più veloce.

    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 in C # 3.0 utilizzando System.Linq si può saltare la lista intermedio:

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

Usa Array.CreateInstance per creare un array dinamico.

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

In genere, gli array richiedono costanti per inizializzare la loro dimensione. Si potrebbe spaziare su nvPairs una volta per ottenere la lunghezza, poi "dinamicamente" creare un array usando una variabile per la lunghezza come questo.

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

Non lo consiglio, però. Basta rimanere con il

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

soluzione. Non è che molto meno performante, e il modo più bello.

È possibile creare un array dinamico in questo modo:

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

    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top