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?
Pontos de interesse:
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
0 Asked on September 26, 2021 by erik-exdon
2 Asked on September 26, 2021
2 Asked on September 26, 2021 by sidnei-andrade
1 Asked on September 26, 2021 by daniela-morais
3 Asked on September 26, 2021 by david-coelho
1 Asked on September 26, 2021 by lopes-boa
1 Asked on September 26, 2021 by diogo-costa
1 Asked on September 26, 2021 by caio-coutinho
1 Asked on September 26, 2021 by bruno-lima-coaracy
1 Asked on September 26, 2021 by lima
3 Asked on September 26, 2021 by lucas-michel-da-silva
1 Asked on September 26, 2021 by faillen
1 Asked on September 26, 2021 by el-capitan-comandante
1 Asked on September 26, 2021
Get help from others!
Recent Answers
Recent Questions
© 2023 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP