,
Extension methods were added in C# 3.0 and are a great way to add commonly used functionality to your projects in an object oriented way that cuts down on repetitive code. While extension methods are an underlying feature of C#, I am going to focus on their use in a view in an ASP.NET MVC project. The same principles apply to using them in any C# code..
I write a lot of ecommerce-related web applications, so I am constantly having to output prices formatted as currency. While I could just use the String.format method directly in a view, I prefer something a little more elegant and less repetitive. By adding a ToCurrency method to the decimal type, I can easily output a formatted string.
Start by adding a new class to your project with its own namespace, for example myproject.Extensions:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace myProject.Extensions {
Add a static class – this class will have methods added to it that will become your extension methods:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace myProject.Extensions { public static class Extensions { } }
Each static method you add to the class will become an extension method. You tie it to a particular type by using the this keyword and a parameter of the type you want to extend:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace myProject.Extensions { public static class Extensions { public static string ToCurrency(this decimal amount) { return String.Format("{0:C}", amount); } } }
The ToCurrency method will be added to the decimal type because it is specified as the parameter type and includes the keyword this. I am simply passing the parameter to the String.Format method and returning a formatted string.
Calling the extension method either in other code such as a controller or within a view is simple. You just need to be certain to include the namespace in your class or view with a using statement. This is an example of it in a Razor view:
@model myProject.Models.Product @using myProject.Extensions; <span>@Model.Price.ToCurrency()</span>
The price property of the Product class is a decimal, so the method is available as if it were part of the underlying type.
You can add extension methods to any class the same way. Another example is providing a formatted address for an address object:
public static string GetFormatted(this Address address) { string a=address.Name+"<br>"; if(address.Company!=null) { a+=address.Company+"<br>"; } a+=address.Address1+"<br>"; if(address.Address2!=null) { a+=address.Address2+"<br>"; } a+=address.City+", "+address.State+" "+address.Zip return a; }
Then, within a view, you can easily output a formatted address without having to put all the logic into the view:
@Model myProject.Models.Order @using myProject.Extensions <div> @Model.BillingAddress.GetFormatted() </div>
Since the BillingAddress property of the Order object is of type Address, the extension method is available as if it were a native part of the class. While you could add the method directly to the underlying class, if you are working with Entity Framework or a class you may not have the source code to, you can extend it without having to modify the original class.
While you could just as easily create a library of functions to call, extension methods provide a more elegant solution to code reuse and providing utility functions. The can even be put into a separate class library project to reuse them between projects.
For more information about Extension methods, see:
http://weblogs.asp.net/dwahlin/archive/2008/01/25/c-3-0-features-extension-methods.aspx
http://csharp.net-tutorials.com/csharp-3.0/extension-methods/