Pergunta

Eu ainda sou novo para C # e eu estive lutando com várias questões sobre matrizes. Eu tenho uma matriz de objetos de metadados (pares de valores de nome) e eu gostaria de saber como criar apenas o número de "InputProperty" objetos que eu realmente precisa. Neste circuito eu definir arbitrariamente o número de elementos a 20 e eu tento salvar quando a entrada torna-se nulo, mas o serviço web no fim de recepção de isto não faz como quaisquer elementos nulos passados ??para ele:

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

Em resumo, dizem que eu só tenho 3 pares NameValue na matriz de entrada acima? Em vez de alocar 20 elementos para a matriz chamada ip, como pode codificar isso para ip é somente tão grande quanto ele precisa ser. O objecto de actualização é passado através de um outro modo de serviço Web serialização é importante (isto é, que não podem usar NameValueCollection, etc).

P.S. É a única maneira de followup em uma pergunta postada através do "adicionar comentários" facilidade?

Foi útil?

Solução

Se você não quiser usar um List, ArrayList, ou outra coleção dinamicamente de tamanho e, em seguida, converter para uma matriz (que é o método eu recomendo, por sinal), então você vai ter que alocar o matriz para seu tamanho máximo possível, manter o controle de quantos itens você colocar nele, e, em seguida, criar uma nova matriz com apenas esses itens nele:

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

Um método alternativo seria para sempre update.Items = ip; atribuir e, em seguida, redimensionar, se necessário:

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

É menos código, mas provavelmente vai acabar fazendo a mesma quantidade de trabalho (ou seja, a criação de uma nova matriz e copiar os itens antigos).

Outras dicas

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

Ou, você pode usar uma lista como assim:

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

Outra coisa que eu gostaria de salientar, em C # você pode delcare seu uso variável int em um para a direita loop dentro do loop:

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

E só porque eu estou no clima, aqui está uma maneira mais limpa de fazer esse 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;
}

Será que é preciso para ser um array? Se você usar um ArrayList ou um dos outros objetos disponíveis em C #, você não tem esta limitação para o conteúdo com. Hashtable, IDictionnary, IList, etc .. todos permitem um número dinâmico de elementos.

Use esta:

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

Você pode usar Lista de dentro do método e transformá-lo em uma matriz no final. Mas eu acho que, se falamos de um valor máximo de 20, seu código é mais 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;
    }

Ou em C # 3.0 usando System.Linq você pode ignorar a lista intermediário:

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

Use Array.CreateInstance para criar uma 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;
    }

Normalmente, as matrizes exigem constantes para inicializar o seu tamanho. Você poderia varrer nvPairs uma vez para obter o comprimento, em seguida, "dinamicamente" criar uma matriz usando uma variável para o comprimento como esta.

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

Eu não recomendaria isso, porém. Basta ficar com o

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

solução. Não é que muito menos eficaz, e muito melhor olhando.

Você pode criar uma matriz dinâmica desta forma:

 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top