Check data before using as array element

Asked

Viewed 101 times

4

In chat was asked something about data entry validation to avoid error of picking outside the permitted range. I found the question interesting and pity that was not posted here, I am posting:

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

How to avoid error?

1 answer

7


Points of interest:

  • Contracts
  • Programming errors are solved by fixing them
  • Some reorganizations
  • There is something ready that works better

There are some ways I’ve enjoyed using contracts. It has some disadvantages, but in general helps and should be used more, the . NET uses all the time in its codes. If you don’t like him, just switch to one if and make an exception (it is the same as the Requires() does internally in most cases, but there are some that it can be removed from execution, see below). Change anything? Not much, just that the mistake is more specific, and it has positive implications, but it can change something important.

Another possibility is to use a Assert() that can be guaranteed shut down, which can be a good, after all the error Out of Bounds is programming error and the only possible solution is to fix the error, the only thing we can do is to ensure that a well tested code gives the error at development time and if there is any error in the call also have the problem solved. If you are sure that the error no longer happens the Assert() does not go to production, already the Requires() can go, but at the same time it can be safer if you’re not so sure.

In the current version of Visual Studio this withdrawal of Requires() is not automatic, need to install and configure the use of analysis and automatic withdrawal of contracts.

Another possibility is to do nothing, after all programming error solves and does not try to circumvent, and I have opted for it. But you can do something like this:

Example parameter names are not good, are misleading.

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

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

I won’t put it to spin online because these environments are limited, the great advantage is when the tool helps, Visual Studio for example can report problems during development, or has tools that generate tests for you based on the contract found within the method (I need to catch up because it’s changed since I last used it).

But you can simplify that and use the Array.Copy() that already exists in .NET. If you want to only make one wrap simple to consider only the beginning of the font and it fill alone the beginning of the destination and the size of the copy.

I posted more to show that there are alternatives, some that few know, There are ways to solve without doing anything in the code and there are ways to use what already has ready that will be much faster because make a copy blittable, as far as it goes.

  • What is that Requires(bool, string) makes? I found it interesting.

  • 1

    Check if the argument is ok.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.