Question

Je suis encore nouveau pour C # et j'ai été aux prises avec divers problèmes sur les tableaux. J'ai un tableau d'objets de métadonnées (paires de valeurs de nom) et je voudrais savoir comment créer seulement le nombre d'objets « InputProperty » que j'ai vraiment besoin. Dans cette boucle, j'ai fixé arbitrairement le nombre d'éléments à 20 et je tente de renflouer lorsque l'entrée devient nulle, mais le service Web sur la réception de fin de cela ne ressemble à aucun des éléments nuls qui lui sont transmises:

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 résumé, disons que je n'ai 3 paires de nameValue dans le tableau d'entrée ci-dessus? Plutôt que d'allouer 20 éléments pour le tableau appelé ip, comment peut coder ce si ip est seulement aussi grande qu'elle doit être. L'objet de mise à jour est passé à travers une autre webservice si sérialisation est important (à savoir que je ne peux pas utiliser NameValueCollection, etc.).

p.s. Est-ce le seul moyen de followup sur une question posée par l'installation « ajouter des commentaires »?

Était-ce utile?

La solution

Si vous ne souhaitez pas utiliser un List, ArrayList ou toute autre collection dynamique de taille, puis convertir à un tableau (c'est la méthode que je vous recommande, en passant), alors vous devrez allouer les tableau à sa taille maximale possible, garder une trace de combien d'articles que vous mettez dans, puis créer un nouveau tableau avec seulement les éléments qu'il contient:

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

Une autre méthode serait de toujours attribuer update.Items = ip; puis redimensionner si nécessaire:

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

Il est moins de code, mais finira probablement par faire la même quantité de travail (à savoir la création d'un nouveau tableau et copier les éléments anciens).

Autres conseils

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

Ou, vous pouvez utiliser une liste comme ceci:

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

Une autre chose que je voudrais souligner, en C #, vous pouvez delcare votre utilisation variable de type int dans une boucle à l'intérieur de la boucle:

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

Et juste parce que je suis dans l'ambiance, voici un moyen plus propre à faire cette méthode OMI:

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

n'est nécessaire d'être un tableau? Si vous utilisez un ArrayList ou l'un des autres objets disponibles en C #, vous n'aurez pas cette limitation au contenu avec. Hashtable, IDictionnary, IList, etc .. tout cela permet un certain nombre d'éléments dynamiques.

Utilisez ceci:

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

Vous pouvez utiliser la liste dans la méthode et le transformer en un tableau à la fin. Mais je pense que si l'on parle d'une valeur maximale de 20, votre code est plus rapide.

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

Ou en C # 3.0 en utilisant System.Linq vous pouvez sauter la liste intermédiaire:

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

Utilisation Array.CreateInstance pour créer dynamiquement un tableau.

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

En règle générale, les tableaux nécessitent des constantes pour initialiser leur taille. Vous pouvez balayer nvPairs une fois pour obtenir la longueur, puis « dynamiquement » créer un tableau en utilisant une variable pour la longueur comme celui-ci.

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

Je ne recommanderais pas, cependant. Il suffit de coller avec le

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

. Ce n'est pas beaucoup moins performant, et beaucoup mieux regarder.

Vous pouvez créer un tableau dynamique de cette façon:

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

    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top