Showing posts with label Extension methods. Show all posts
Showing posts with label Extension methods. Show all posts

13 October 2018

difference between FirstOrDefault () and SingleOrDefault()

Recently one of my junior colleague working in .NET asked me about what is the difference between the FirstOrDefault and SingleOrDefault() methods.

Both FirstOrDefault() and SingleOrDefault() are the extension methods on the System.Collections.Generic.IEnumerable defined in System.Linq namespace.

The difference is pretty simple

Enumerable.SingleOrDefault()

SingleOrDefault() method returns the element which matches the condition. If no element matches the condition, then the method returns the default of value of the source type (default(TSource))

If more than one elements match the condition specified, it throw the Exception (InvalidOperationException) Enumerable.FirstOrDefault()

Enumerable.FirstOrDefault()

The way FirstOrDefault() method works is same as the Enumerable.SingleOrDefault() except that it doesn’t throw an exception if more than one element matches the condition. It just returns the first matching record.

How to choose between FirstOrDefault () and SingleOrDefault() methods?

If you know for sure that, there should only be one record present in the collection matching specified condition and presence of more than one record in the collection matching the condition indicates an error, then use the SingleOrDefault() method. So in error conditions, you will rightly get an exception.

If there could be multiple matching records for the specified condition in a collection and just you want the first one, then go ahead and use FirstOrDefault() method.

15 August 2015

use of extension methods in data access code in C#

Already there are 2 articles posted on the blog about extension methods in C#. I'm writing one more on the same subject because extension methods can be used to reduce the number of lines of code to be written while improving the readability aspect of the code.

Earlier article on the extension methods

  1. Extension methods introduction and overview
  2. A practical example usage of extension methods in C#

Problem statement while writing repository code

Consider a scenario where you are writing repository code for saving customer details. The Customer Repository class usually will have Create, Read, Update and Delete methods(the typical CRUD operations).

public class CustomerRepository
{
  public void Create(Customer newCustomer)
  {
     //Other code...
     if (contact.Email != null)
       {
       sqlCommand.Parameters["@p_customer_email"].Value = 
               newCustomer.Email;
       }
    else
       {
      sqlCommand.Parameters["@p_customer_email"].Value =
                 DBNull.Value;
      }
   }
}

When new customer email is NULL and if you don't assign the Database specific NULL value(DBNull.Value), you are bound to get an EXCEPTION saying, missing parameter value or parameter value not provided for @p_customer_email while executing the stored procedures.(You will see this error only when in a stored procedure you have indicating @p_customer_email parameter as mandatory.)

To avoid such errors, you will end up in writing above NULL check for parameter value and assign DBNull.Value to SQL parameter when actual value is NULL.

But, when the number of such nullable parameter increases, the lines of code you have written also increases resulting in too much of duplicates lines of code. Now let's see, how this code duplication can be removed by using Extension methods.

Solution using extension methods

  1. Create a static helper class and add a extension method like below:
    namespace DBExtensions
    {
    public static class DBExtensions
     {
      public static object GetDatabaseValue(this string value)
        {
          if (value != null)
                    return value;

                return DBNull.Value;
        }
     }
    }
  2. Now in the customer repository class import the namespace in which DBExtensions class is defined
    using DBExtensions;
  3. Let's use the extension method added on the string class
    public class CustomerRepository
    {
      public void Create(Customer newCustomer)
      {
         //Other code...
         sqlCommand.Parameters["@p_customer_email"].Value =
         newCustomer.Email.GetDatabaseValue();
       }
    }

Advantage of extension methods

By using extension methods, the number of lines of code is reduced from 4 lines to just 1 line of code. Duplicated lines of code is reduced (Now code is inline with DRY principle). Also with the extension methods, code readability is improved.

15 October 2014

FirstOrDefault() method, when it will return null

Few days back me and one of my friend were looking at a peice of code written in C# language. A line of code which was using FirstOrDefault() extension method for IEnumerable got my attention and we ended up in argument. The code was something like below.

public class Student
{
  public string FirstName;
  public string LastName;
  public string USN;
}

using System.Linq;
class Program
{
   static void Main(string[] args)
   {
    /*line 1*/
    List<Student> studentList = new List<Student>();

    /*line 2*/
    Student student = studentList.FirstOrDefault();

    /*line 3*/string name = student.FirstName;
    Console.Read();
   }
}

The code in the line 3 code got the attention and I said NullReferenceException will be thrown as Student being reference type whose default value will be null. For this, my friend said NO, FirstOrDefault() will get the empty instance value which will not be null so there will be no exception. To prove him wrong I had to execute the above C# code and show the below exception.

FirstOrDefault extension method and when it will return null

The method FirstOrDefault<TSource> will return the default of TSource when IEnumerable collection is empty. Here TSource can either be a value type or reference type.

  • If TSource is a reference type (e.g, Class), then its default value is null.
  • If TSource is a value type then it will return the default value which is not null. F.g, if TSource is a integer then default value will be 0.

To verify the default value you can use default(TSource) construct as shown below.

// Will print nothing, as default value of 
// reference type Student is null.
Console.WriteLine(default(Student)); 

// Will print 0
Console.WriteLine(default(int));