AnswerBun.com

Verificar dados antes de usar como elemento de array

Stack Overflow em Português Asked on January 4, 2022

No chat foi perguntado algo sobre validação de entrada de dados para evitar erro de pegar fora da faixa permitida. Achei a pergunta interessante e pena que não foi postada aqui, estou postando:

public static T[] ReplaceRange<T>(this T[]input, T[] replacement, int start) {
    for (int i = start; i < input.Length; i++) {
        T replacementItem = replacement[i - start];
        input[i] = replacementItem;
    }
    return input;
}

Como evitar o erro?

One Answer

Pontos de interesse:

  • Contratos
  • Erros de programação são resolvidos consertando-os
  • Algumas reorganizações
  • Existe coisa pronta que funciona melhor

Existem algumas formas, eu tenho gostado de usar contratos. Ele tem algumas desvantagens, mas em geral ajuda e deveria ser usado mais, o .NET usa o tempo todo em seus códigos. Se não gostar dele é só mudar para um if e lançar uma exceção (é o mesmo que o Requires() faz internamente na maioria dos casos, mas tem alguns que ele poderá ser retirado da execução, veja abaixo). Muda alguma coisa? Não muito, apenas que o erro é mais específico, e isso tem implicações positivas, mas pode mudar algo importante.

Uma outra possibilidade é usar um Assert() que pode ser garantidamente desligado, o que pode ser uma boa, afinal o erro Out of Bounds é erro de programação e a única solução possível é consertar o erro, a única coisa que podemos fazer é garantir que um código bem testado dê o erro em tempo de desenvolvimento e se tiver algum erro na chamada também tenha o problema resolvido. Se tiver certeza que o erro não acontece mais o Assert() não vai para produção, já o Requires() pode ir, mas ao mesmo tempo pode ser mais seguro se não tiver tanta certeza assim.

Na versão atual do Visual Studio essa retirada do Requires() não é automática, precisa instalar e configurar o uso de análise e retirada automática dos contratos.

Outra possibilidade é fazer nada, afinal erro de programação se resolve e não tenta contornar, e eu tenho optado por isso. Mas pode fazer algo assim:

Os nomes dos parâmetros do exemplo não são bons, são enganosos.

using static System.Console;
using static System.Diagnostics.Contracts.Contract;

public class Program {
    public static void Main() {
        foreach (var item in ReplaceRange(new int[] {0, 1, 2, 3, 4}, new int[] {5, 6, 7, 8, 9}, 2)) WriteLine(item);
    }
    public static T[] ReplaceRange<T>(T[] source, T[] destination, int start) {
        Requires(start >= 0, "O índice de início não pode ser menor que zero");
        Requires(start < source.Length, "O índice de início não pode ser maior que o fim do array");
        Requires(destination.Length >= source.Length - start, "O índice de início não pode ser maior que o que cabe");
        for (int i = start, j = 0; i < source.Length; i++, j++) destination[i] = source[j];
        return destination;
    }
}

Veja funcionando no ideone. E no .NET Fiddle. Também coloquei no GitHub para referência futura.

Não vou colocar para rodar online porque esses ambientes são limitados, a grande vantagem é quando a ferramenta ajuda, o Visual Studio por exemplo pode informar de problemas durante o desenvolvimento, ou tem ferramentas que geram testes para você baseado no contrato encontrado dentro do método (preciso até me atualizar porque mudou desde a última vez que usei).

Mas pode simplificar isso e usar o Array.Copy() que já existe no .NET. Se quiser só faça um wrap simples para considerar apenas o início da fonte e ele preencher sozinho o início do destino e o tamanho da cópia.

Postei mais com intuito de mostrar que tem alternativas, algumas que poucos conhecem, tem maneiras de resolver sem fazer nada no código e há maneiras de usar o que já tem pronto que será bem mais rápido porque fará uma cópia blittable, até onde dá.

Answered by Maniero on January 4, 2022

Add your own answers!

Related Questions

Parar movimento com animation css

1  Asked on September 26, 2021 by jeanalves

   

Como executar uma paginação com PDO?

1  Asked on September 26, 2021

     

Implicações de @Autowired em construtor e fora

1  Asked on September 26, 2021 by daniela-morais

   

Menu Dropdown Responsivo

2  Asked on September 26, 2021 by user77295

     

Agrupar um array de objetos

3  Asked on September 26, 2021 by david-coelho

     

Sobrepor texto em uma imagem com flex box

1  Asked on September 26, 2021 by lopes-boa

     

TreeView com Nodes & Childs através de base de dados SQL

1  Asked on September 26, 2021 by diogo-costa

   

Erro ‘Método não-estático requer um destino.’

1  Asked on September 26, 2021 by caio-coutinho

     

Consulta de coleções firebase

1  Asked on September 26, 2021 by lima

         

useState não atualiza – ReactJS

3  Asked on September 26, 2021 by lucas-michel-da-silva

       

como incrementar um array de objeto javascript em loop?

1  Asked on September 26, 2021 by faillen

 

Adicionar character no fim da linha

3  Asked on September 26, 2021 by arcyde

   

Escala de serviço filtro de datas no plano de férias

1  Asked on September 26, 2021 by el-capitan-comandante

     

Problema ao validar input

1  Asked on September 26, 2021 by andr-cabral

   

“List Comprehensions” vale a pena?

2  Asked on September 26, 2021 by gui-reis

     

Ask a Question

Get help from others!

© 2023 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP