0

Is there a simple^ way of getting the value 'null' if an array element does not exist?

For example, in the code below sArray has 3 elements and the first 3 calls to SomeMethod work (prints true), however the 4th call SomeMethod(sArray[3]); gives me an IndexOutOfRangeException. Is there a way to make the 4th call to SomeMethod print false?

    static void Main(string[] args)
    {
        int[] sArray = new int[]{1,2,3};
        SomeMethod(sArray[0]);
        SomeMethod(sArray[1]);
        SomeMethod(sArray[2]);
        SomeMethod(sArray[3]);
    }
    static void SomeMethod(int? s) => Console.WriteLine(s.HasValue);

^Would prefer single line expression

4
  • 2
    You can prevent from exception then why you need this type solution you can call somemethod over loop through sArray it will not throw exception Commented Sep 25, 2018 at 3:22
  • 1
    Downvoted: This appears to be a XY Problem. Commented Sep 25, 2018 at 3:39
  • Arrays in C# have a .Length property which you can check before calling SomeMethod. The typical approach is to loop through each element of the array rather than guessing whether or not an index is valid: for (int i = 0; i < sArray.Length; i++) { SomeMethod(sArray[i]); } Commented Sep 25, 2018 at 4:11
  • @ErikPhilips I don’t agree, I can’t post the actual code as its confidential, I asked the question in the most generalised way I can and in a way that would be more beneficial to readers in the future instead of getting bogged down into the specifics of my problem. Commented Sep 25, 2018 at 6:53

5 Answers 5

6

How about an extension method?

public static T? TryGet<T>(this T[] source, int index) where T: struct
{
    if (0 <= index && index < source.Length)
    {
        return source[index];
    }
    else
    {
        return null;
    }
}

Then you could write:

static void Main(string[] args)
{
    int[] sArray = new int[]{1,2,3};
    SomeMethod(sArray.TryGet(0));
    SomeMethod(sArray.TryGet(1));
    SomeMethod(sArray.TryGet(2));
    SomeMethod(sArray.TryGet(3));
}
Sign up to request clarification or add additional context in comments.

3 Comments

This would also work in my case however i decided to go with mjwills's answer as its more efficient.
I hope you're referring to his non-LINQ answer because the LINQ version is quite expensive (it's O(n) for an array access and creates three auxiliary objects).
Yes, his non-LINQ answer
6

There is a Linq method ElementAtOrDefault

To use it the way you want to (returning null) you will need ti change the underlying type of your array to nullable int:

    int?[] sArray = new int?[]{1,2,3};
    SomeMethod(sArray.ElementAtOrDefault(1000));

2 Comments

This would also work in my case however i decided to go with mjwills's answer as its more efficient
foreach is the way to go, yes :)
2
SomeMethod(sArray.Skip(3).Select(z => (int?)z).FirstOrDefault());

is a working replacement of:

SomeMethod(sArray[3]);

The former will call SomeMethod with null (while the latter will throw an exception if the array doesn't have at least 4 entries).

In Skip(3) the 3 can be changed to whatever index you want to retrieve from the array. The Select is needed to project the int into a int? so that FirstOrDefault returns either the 4th element or null.

If you don't want to use LINQ then you could use:

SomeMethod(sArray.Length > 3 ? sArray[3] : (int?)null);

instead.

Or consider using:

foreach (var entry in sArray.Take(4))
{
    SomeMethod(entry);
}

to loop through up to 4 elements of the array (it will work fine if there are fewer than 4 - it will just make fewer calls to SomeMethod).

1 Comment

I've used the non-LINQ method in your post as its the most efficient
1

Arrays in C# have a .Length property which you can check before trying to pass an item from one to SomeMethod, and the typical approach is to loop through each element of the array rather than guessing whether or not an index is valid:

for (int i = 0; i < sArray.Length; i++) 
{
    SomeMethod(sArray[i]); 
}

You will not be able to avoid an IndexOutOfRangeException if you reference an index in an array that doesn't exist.


However, if you really want a method with this type of functionality, you could simply modify your existing code to check whether or not the index specified is greater than the length of the array.

Since your array is an int[] (and not an int?[]), all valid indexes will have a value. Also, we can use the ?. to handle cases where the array itself may be null:

private static void SomeMethod(int[] array, int index) => 
    Console.WriteLine(index >= 0 && index < array?.Length);

Then in use, instead of passing an array item with an invalid index (which will always throw an IndexOutOfRangeException), you would pass the array itself and the index separately:

static void Main()
{
    int[] sArray = new int[] { 1, 2, 3 };

    SomeMethod(sArray, 0);
    SomeMethod(sArray, 1);
    SomeMethod(sArray, 2);
    SomeMethod(sArray, 3);
    SomeMethod(null, 0);

    GetKeyFromUser("\nPress any key to exit...");
}

Output

enter image description here

2 Comments

This looks like the most sensible approach, and bringing some rationality back to the question. Upvote
This approach wouldn’t work for me as I need to pass in multiple elements from the array into a method, i.e. SomeMethod((strin)sArray[0],(int?) sArray[1]). I just made the question more general. This might help other tho.
-1

in this case I'll suggest you to create a extension somewhere in your code like this

static class ArrExt
{
    public static int? Get(this int[] arr, int i)
    {
        return (i >= 0 && i < arr.Length) ? arr[i] : default(int?);
    }
}

then you can do this

int[] sArray = new int[] { 1, 2, 3 };
SomeMethod(sArray.Get(0));
SomeMethod(sArray.Get(1));
SomeMethod(sArray.Get(2));
SomeMethod(sArray.Get(3));

okay this is not a single line solution I know, but it's easier for both programmer and computer.

1 Comment

This is locked to int

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.