-1

So I have made a simple code, which passes two different arrays to a method, to check for Exceptions. But there is one problem - when I pass the arrays, if an exception is cached, in my Exceptions "nameof" part, it doesn't say which array was the one, what made the exception. I need to correct that. So do you have any ideas, how I can do this in my code?

public class CommonEnd
{
    public bool IsCommonEnd(int[] a, int[] b)
    {
        ValidateArray(a);
        ValidateArray(b);
        return a.First() == b.First() || a.Last() == b.Last();
    }

    private void ValidateArray(int[] array)
    {
        if (array == null)
        {
            throw new ArgumentNullException(nameof(array), "Array is NULL.");
        }

        if (array.Length == 0)
        {
            throw new ArgumentOutOfRangeException(nameof(array), "Array length can't be smaller that 1");
        }
    }
}
  • Your exception handling looks pretty wierd. There are two articles that helped me a lot getting a grip of Exception handling. And I link them a lot. I think they might help you here too: http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx | http://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET – Christopher Feb 12 '18 at 14:32
  • So you want to know which of the two calls to `ValidateArray` produced the error? – MakePeaceGreatAgain Feb 12 '18 at 14:34
  • That is exactly what I need – Ričards Mauriņš Feb 12 '18 at 14:35
  • I'm using Xunit testing, that is why those Exceptions are written as they are seen. – Ričards Mauriņš Feb 12 '18 at 14:37

2 Answers2

1

Your ValidateArray method receives some piece of data. For convenience it names that piece "array". Other methods might have references to the same data and they might have their own names for it. For instance, the method which called IsCommonEnd used to name that array "myPreciousArray", IsCommonEnd named it "b" and ValidateArray calls it "array". Even if there was a way for ValidateArray to access all of those other names for the array, which one should you choose?

If you need to distinguish between instances, why not handle that in the place where the instances are obviously identifiable? Like in your IsCommonEnd method? Something like this:

public bool IsCommonEnd(int[] a, int[] b)
{
    try
    {
    ValidateArray(a);
    }
    catch(ArgumentNullException ex)
    {
        // you know your 'a' array is null, do whatever you want to do about that
        throw; // if you need this exception to propagate, of course

    }
    catch(ArgumentOutOfRangeException ex)
    {
        // you know your 'a' array is too small, do whatever you want to do about that
        throw; // if you need this exception to propagate, of course

    }
    // the same about 'b'
    try
    {
    ValidateArray(b);
    }
    catch(ArgumentNullException ex)
    {
        // you know your 'b' array is null, do whatever you want to do about that
        throw; // if you need this exception to propagate, of course

    }
    catch(ArgumentOutOfRangeException ex)
    {
        // you know your 'b' array is too small, do whatever you want to do about that
        throw; // if you need this exception to propagate, of course

    }
    return a.First() == b.First() || a.Last() == b.Last();
}
rs232
  • 1,248
  • 8
  • 16
1

nameof(array) will always just return the string array. In order to know whether a or b went wrong, you can pass another parameter and use nameof one level higher

private void ValidateArray(string which, int[] array)
{
    if (array == null)
    {
        throw new ArgumentNullException(nameof(array), $"Array {which} is NULL.");
    }

    if (array.Length == 0)
    {
        throw new ArgumentOutOfRangeException(nameof(array), $"Array {which} length can't be smaller that 1");
    }
}

And in the calling method:

public bool IsCommonEnd(int[] a, int[] b)
{
    ValidateArray(nameof(a), a);
    ValidateArray(nameof(b), b);
    return a.First() == b.First() || a.Last() == b.Last();
}
Jamiec
  • 133,658
  • 13
  • 134
  • 193