Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drop 'Where' and move the condition into the 'First' in LINQ

Tags:

c#

linq

sonarqube

I have a windows application which has some similar code as below.
As class named Order.

class Order{
 public string Orderid { get; set; }
 public string CustName { get; set; }
}

Now, in another class in this application, object for Order class is created and value is assigned to it.

Order order = new Order();
order = JObject.Parse(some JSON data).ToObject<Order>();

Now I want to extract the CustName based on Orderid from order. For this I have used LINQ.

string custName = order.Where(s => s.Key == "o123").First().Value;

I'm using Sonarqube to check the code quality. When I run the SonarQube tool , it is showing that I need to refactor my code where I have used LINQ. This is the exact line it shows.

Drop 'Where' and move the condition into the 'First'.

I have searched for it a lot but couldn't understand what it is trying to say. Can anyone explain me how to refactor this line , so that it passes the SonarQube expectations.
Any input is highly helpful.Thanks.

like image 832
CrazyCoder Avatar asked Dec 18 '22 22:12

CrazyCoder


2 Answers

You are perfoming an operation in two steps when you could do that by using the First lambda expression

string custName = order.First(s => s.Key == "o123").Value;

Linq method First definition:

First<TSource>(this IEnumerable<TSource>, Func<TSource, Boolean>)
  • First parameter is the IEnumerable you are using (Linq are extension methods)
  • Second parameter allows you to set the filter declaring a Func<TSource, Boolean> as parameter, that you could define as s => s.Key == "o123"
like image 124
X.Otano Avatar answered Feb 05 '23 19:02

X.Otano


What it is telling you is that the Where is unnecessary, and the code can be expressed as this:

string custName = order.First(s => s.Key == "o123").Value;

The logic of the original code is this:

"look through the list to find any matches, and take the first"

Which is the same as the changed code:

"take the first match in the list"

Note though that this code will throw an exception if there is no match. If there's ever a possibility that there will not be a matching customer, use FirstOrDefault instead:

string custName;
var customer = order.FirstOrDefault(s => s.Key == "o123");

if (customer != null) {
   custName = customer.Value;
}
else {
    // code to handle no match
}
like image 40
stuartd Avatar answered Feb 05 '23 18:02

stuartd