Book Image

Instant .NET 4.5 Extension Methods How-to

By : Shawn Ricardo Mclean
Book Image

Instant .NET 4.5 Extension Methods How-to

By: Shawn Ricardo Mclean

Overview of this book

.NET extension methods is an essential feature to know and understand for all .NET developers. Usage of extension methods is found in applications ranging from small to large scale enterprise systems built using the .NET framework. Create and use extension methods the correct way to save your development time and maintainability costs. Instant .NET 4.5 Extension Methods How-to is a practical, hands-on guide that provides you with a number of clear, step-by-step exercises that will help you take advantage of the real power that is behind extension methods and gives you good knowledge of how to use them in your .NET applications. This book covers how to create, write, and use different types of extension methods. It will take you through a number of clear, practical recipes that will help you take advantage of the power of extension methods in the quickest possible way. You will also learn exactly how to create extension methods on strings, interfaces, classes such as IQueryable and IEnumerable, and so on. You will write them from scratch and then use them practically in your application. You will also learn the most suitable scenarios for using these extension methods.You will learn everything you need to know about creating your own extension methods and using them and other external extension methods.
Table of Contents (6 chapters)

Extension methods with lambda expressions (Become an expert)


Lambda expressions are used in place of anonymous methods and delegates. They are used extensively in the LINQ namespace and other enumerated data types for their readability of condition matching.

Getting ready

Refer to the ArrayExtensions.cs and FuncExtensions.cs file in the ExtensionMethods.Library project for the extension methods. These methods are used in the Program.cs file in the ExtensionMethods.Console project.

How to do it...

The following code snippet shows an overloaded extension method ToList() which accepts a mapping function as a lambda expression:

public static class ArrayExtensions
{
    /// <summary>
    /// Converts an array of items to List<T> using a mapping function
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="items"></param>
    /// <param name="mapFunction"></param>
    /// <remarks>Taken from http://www.extensionmethod.net/csharp/array/tolist-t-func-object-t-func</remarks>
    /// <returns></returns>
    public static List<T> ToList<T>(this Array items, Func<object, T> mapFunction)
    {
        if (items == null || mapFunction == null)
            return new List<T>();

        List<T> coll = new List<T>();
        for (int i = 0; i < items.Length; i++)
        {
            T val = mapFunction(items.GetValue(i));
            if (val != null)
                coll.Add(val);
        }
        return coll;
    }
}

The following code is another extension method that focuses on extending a lambda expression or function to memorize the execution if the data is the same:

public static class FuncExtensions
{
    /// <summary>
    /// Memoize a function
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="func">the function to memoize</param>
    /// <remarks>http://www.extensionmethod.net/csharp/func/memoize-t-tresult</remarks>
    /// <returns></returns>
    public static Func<T, TResult> Memoize<T, TResult>(this Func<T, TResult> func)
    {
        var t = new Dictionary<T, TResult>();
        return n =>
        {
            if (t.ContainsKey(n)) return t[n];
            else
            {
                var result = func(n);
                t.Add(n, result);
                return result;
            }
        };
    }
}

The following code shows the use of the extension methods:

private static void DoTaskEleven()
{
    Func<string, string> format = new Func<string, string>(s =>
    {
        // a long running operation
        System.Threading.Thread.Sleep(2000);
        return String.Format("hello {0}", s);
    }).Memoize();
    // takes 2000 ms
    for (int a = 0; a < 100;a++ )
    {
        System.Console.WriteLine(format(" world"));
    }
}

private static void DoTaskElevenPart2()
{
    User[] users = new User[]
                        {
                            new User
                                {
                                    FirstName = "Shawn", 
                                    LastName = "Mclean"
                                },
                            new User
                                {
                                    FirstName = "Derron", 
                                    LastName = "Brown"
                                }
                        };
    var userVMs = users.ToList<UserViewModel>(o =>
                        {
                            var item = (User) o;
                            return new UserViewModel
                            {
                               FullName = (item).GetFullName(),
                                  UserId = item.UserId
                               };
                     });
}

How it works...

The first code snippet, ToList(), is an extension of the array object which takes a mapping lambda expression function as a parameter. This function is then used to convert the values of the array to the type specified in the template definition. When calling this extension method, we simply apply the class type to the template and pass in the expression as a parameter as seen in the DoTaskElevenPart2() method in the use cases code snippet

users.ToList<UserViewModel>(o => ...

The second code snippet, Memoize(), is an extension to the Func type. This is an extension method that does not incorporate lambda expressions as parameters but actually extends it. This use case is rare because there are usually better design patterns to use to accomplish the solution. In this method, we Memoize the value passed to the expression to prevent further processing, if it has already been called with that same data before.

The DoTaskEleven() snippet shows the body of the expression containing a sleep function that should take 2 seconds to execute. When Memoize is attached, if the method was already executed before with the same parameters, the body will never get executed again and the return value is returned from the cache, a dictionary in this case.

In this recipe, you have learned how to use lambda expressions to help make your extensions more flexible and also how to extend an actual lambda expression.