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 generics (Become an expert)


Generics in C# allows us to create type-safe definitions of methods and classes without the actual need to commit to an actual data type. You have worked with generic types in the previous recipe, such as enumerated data types and, soon, lambda expression. Generic types can be extended, as shown in the previous recipe; however, there are a few caveats you should keep in mind when extending generics that we will cover in this recipe.

Getting ready

Refer to the GenericExtensions.cs and Models/Users.cs files in the ExtensionMethods.Library project for the extension methods and class. These methods are used in the Program.cs file in the ExtensionMethods.Console project.

How to do it...

The following code shows the Serialize and SerializeUser extension methods that we are using:

public static class GenericExtensions
{
    /// <summary>
    /// Serializes an object to json string
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="entity"></param>
    /// <returns></returns>
    public static string Serialize<T>(this T entity)
    {
        return JsonConvert.SerializeObject(entity);
    }
    /// <summary>
    /// Serializes any type inheriting from IUser to json string.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="entity"></param>
    /// <returns></returns>
    public static string SerializeUser<T>(this T entity) where T : IUser
    {
        //remove password from the object
        entity.Password = string.Empty;
        return JsonConvert.SerializeObject(entity);
    }
}

The following code shows the use of these extension methods:

[TestClass]
public class GenericExtensionTests
{
    [TestMethod]
    public void SerializeObjectTest()
    {
        var obj = new User
                        {
                            FirstName = "Cheyenne",
                            LastName = "Powell",
                            Password = "test"
                        };
        string json = obj.Serialize();
        Assert.IsTrue(json.Contains("test"));
    }

    [TestMethod]
    public void Serialize_IUser_Object_Test()
    {
        var obj = new User
        {
            FirstName = "Cheyenne",
            LastName = "Powell",
            Password = "test"
        };
        string json = obj.SerializeUser();
        //SerializeUser should remove the password
        Assert.IsFalse(json.Contains("test"));
    }
}

How it works...

In the first snippet, we have the Serialize extension method on the generic type T. The purpose of this extension is to serialize an object to a JSON string. This means that this method can be executed on any type.

The following screenshot shows that the IntelliSense treats this as an object type:

Be careful of infinite recursions as you may notice that the method is also available to be called again.

When using this extension method, you may find that it can be called on any type, including strings, integers, and so on. This may cause unintended behaviors and could be, potentially, dangerous.

The second code snippet gives us an upgraded and safer version of this method. SerializeUser utilizes the where clause to place a condition on the type of generic data type this method is exposed to:

public static string SerializeUser<T>(this T entity) where T : IUser

This clause states that this method is only available to those objects that are of type IUser, or inherits from it. In the previous screenshot, you will notice that this extension method is not available to that data type in the IntelliSense. Even though our parameter entity is of type T, the clause tells the compiler it is actually an IUser type, the IntelliSense will operate accordingly.

The purpose of our SerializeUser method is to serialize the object of the IUser type while removing the password from it. In the following image, both methods are available to us in IntelliSense. The compiler sees that obj is of the User type which inherits from the IUser type which tells the IntelliSense to show us SerializeUser.

The following screenshot shows the IntelliSense being activated and displays the available methods for both the object and IUser type:

When working with generics, try to narrow down the types the method will apply to by using the where clause unless you are certain that the method should apply to every data type available to the compiler.

In this recipe, you have have learned generics behave with extension methods with a few things to watch out for and ways to work around them.