Introduction

I must admit I have the latest preview of Visual Studio 2019 installed but I’ve not kept up to date with the new world of .NET 6 and the associated changes in C# which are coming. I did however see a post on LinkedIn the other day by David Callan and it caught my eye. He wrote a post on his wall (is that that it’s called on LinkedIn?) that you could now specify the default value for your FirstOrDefault calls!

Previously up until this point when you called FirstOrDefault, LastOrDefault or SingleOrDefault if there was not the required item in the collection then you would be given the default value of the type which was in the IEnumerable you were querying; for example if you were working with a List<int> then you would be given 0 as a value. You could obviously write your own extension methods to extend this behaviour but that meant you had to handle it all yourself and repeat yourself if moving between code bases. This is now built in.

So what does this mean? Well let’s go and take a brief look at the future.

Going In Depth

So let’s take one of the extension methods and take a closer look at it.

FirstOrDefault in .NET 6 has 4 overloads curently in the preview. This might change so be careful.

The 4 overloads are defined as such - https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.firstordefault?view=net-6.0#overloads

FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource) FirstOrDefault<TSource>(IEnumerable<TSource>, TSource) FirstOrDefault<TSource>(IEnumerable<TSource>) FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

The bottom two are the ones which have been around for as long as Linq as been part of the language. They are the versions which we have come to know and love. But the top two are the ones which are of interest to me in this blog post.

Let’s take a look at the second one first.

FirstOrDefault<TSource>(IEnumerable<TSource>, TSource)

What this signature is saying is that working on an IEnumerable<TSource> then we can specify the second parameter as an instance of TSource to use as the default. We don’t have to be reliant on the type default anymore and it will only be used if the default would have otherwise been used.

List<int> numbers = new List<int>();
var custom = numbers.FirstOrDefault(-1);

In the example above we don’t need to be reliant on getting back 0 which is the default for int anymore. This could be handy when 0 is a valid number in the context of using the list of numbers where as -1 isn’t.

The other override is when the predicate functionality gets involved.

FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)

What this signature is saying is that working on an IEnumerable<TSource> we can specify a predicate, or condition, as a Func where each item in the source will be run against the conditional check one by one. The first item that passes the predicate conditional is then returned. If none of the values match the predicate then the default value is returned from the TryGetFirst processing. Using this overload it would then want to return the TSource instance specified in the original call.

List<int> numbers = new List<int> { 1,2,3,4,5 };
var custom = numbers.FirstOrDefault(x => x > 5, -1);

In the example above as the condition is never met as all the items in the list are either 5 or less then the specified default of -1 is returned.

Conclusion

In this post we have reviewed the new overloads for FirstOrDefault in .NET 6. Both LastOrDefault and SingleOrDefault have similar matching overloads which allows a custom default value to be defined when the methods are being called.

I must admit I had not looking into any new language methods or features in the latest preview because I just don’t have the time to invest at the moment. Seeing David’s post did spark some interest in the new features coming in the new version so I will continue to keep an eye out for any which look interesting. For now though let me know what you think on Twitter @WestDiscGolf and if you see any new interesting features then please get in contact!