,
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/