Tuesday 15 April 2014

Extension Method for Linq to process a user specified default value for FirstorDefault Method if value not exists

In this article we are going to see a Extension method which will use to process a user specified default value if value not exist or met the condition.This kind of default should be there not only for FirstorDefault method and also for another Linq methods can be applicable.

Actually when this idea is came to my mind i gave this as suggestion to the Microsoft to add a overloads for some of them Linq Methods

Suggestion posted in Microsoft as :

While select a Value from Collection using Linq , Using Following Methods First,Last Have Default,In that It is already returning the Default value for that Type if the value not exists in collections, Instead of that return Specify a Default of user specified value in the function parameter of the same type. for Example

List<string> coll=new List<string>();

var value = coll.FirstOrDefault();        // Returns null value if not exists in collection as default value

Instead of doing like this specify the user defined default value of same type

var Value=coll.FirstOrDefault("No"); // if default value specifies return that value if no value presents in collection , If default value not specifies then return default of that type .


Microsoft :

Posted by Microsoft on 2/16/2014 at 2:00 AM
Hey Rajhseg,

Nice suggestion! Nullable<T> has a GetValueOrDefault method which is parameterized similarly. We'll add it to our wishlist for future features. In the meantime for any collection type that has reference type or nullable value type elements a workaround would be to use the null-coalesce operator (??) like so:

List<string> coll = new List<string>();

var value = coll.FirstOrDefault() ?? "No";

This doesn't work for non-nullable value types though. Alternately as a workaround you could define such an extension method yourself. Something like:

internal static class MyLinqExtensions
{
        public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, TSource defaultValue) {
            if (source == null) throw new ArgumentNullException("source");
            IList<TSource> list = source as IList<TSource>;
            if (list != null) {
                if (list.Count > 0) return list[0];
            }
            else {
                using (IEnumerator<TSource> e = source.GetEnumerator()) {
                    if (e.MoveNext()) return e.Current;
                }
            }
            return defaultValue;
        }
}

This would handle any type. It's not as cool as having it just be part of LINQ but it's a convenient fix in the meantime. I'll see if we can add such overloads to FirstOrDefault and the other *OrDefault methods in the future.

Regards,
YYYYYYY | Program Manager | Visual Basic & C# Languages Team



Let we see a sample program how to use that extension method 

    internal static class MyLinqExtensions
    {
        public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, TSource defaultValue)
        {
            if (source == null) throw new ArgumentNullException("source");
            IList<TSource> list = source as IList<TSource>;
            if (list != null)
            {
                if (list.Count > 0) return list[0];
            }
            else
            {
                using (IEnumerator<TSource> e = source.GetEnumerator())
                {
                    if (e.MoveNext()) return e.Current;
                }
            }
            return defaultValue;
        }

    }


Implementation :

    class Employee
    {
        public string Name { set; get; }   

        public int Id { set; get; }

        public string Address { set; get; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Employee> emp = new List<Employee>();
            emp.Add(new Employee(){Address = "Chennai",Id =1,Name = "Rajesh"});
            emp.Add(new Employee() { Address = "Madurai", Id = 2, Name = "Siva" });
            emp.Add(new Employee() { Address = "Coimbatore", Id = 3, Name = "Suresh" });
            emp.Add(new Employee() { Address = "Chennai", Id = 4, Name = "Siva" });


            Employee e =emp.Where(x => x.Name == "Rajesh1").FirstOrDefault(new Employee(){Id = 0,Address = "Default",Name = "Default"});

            Console.WriteLine(e.Name);
            Console.Read();
        }

    }



In the above example you can see the there is no name Rajesh1 so the linq query normally return null as default but because of our extension method we can pass a user defined value as default.


Output:

    Default


From this article you can learn how to  process a user specified default value for FirstorDefault Method if value not exists

No comments:

Post a Comment