The Code Slinger

November 20, 2007

Extension Methods in Action

Filed under: .NET,LINQ,VB.NET — Pete @ 3:54 am
Tags: , ,

Extension methods are a new language feature in C# and VB.NET which in essence is one of the underpinnings of the new LINQ (Language INtegrated Query) syntax new to .NET.

At first look, extension methods seem to “add” functionality to existing types. But in reality they simply allow you the flexibility of making static method calls more intuitive within the framework of your code by allowing you to attach those methods to existing types (which you may or may not have the source-code to).

As an example, I’ve taken a common task that I find myself doing in my code quite a bit. Having a generic List(Of T) of business objects, I want to find the one object in that list that has a particular ID.

27 Public Shared Function GetByID(Of T As PersistLoad)(ByVal a_List As List(Of T), ByVal a_ID As Integer) As T

28 Dim current As T = Nothing

29 For Each obj As T In a_List

30 If obj.ID = a_ID Then

31 current = obj

32 Exit For

33 End If

34 Next

35

36 Return current

37 End Function

Using this generic implementation, I can pass in any list of objects, the ID I want to search for, and either return an object of type T or nothing/null. This works fine, however if I want to do the same for another data type, e.g. like a Dictionary, I have to write a new method that knows how to iterate over that type of object.

The calling code for this implementation would be something like:

112 m_CurrentBarcode = ExtensionsRegular.GetByID(m_Barcodes, a_BarcodeID)

Notice that I have to pass in as an input parameter the actual list of objects (in this case, barcodes)? Additionally, the method is simply called from a static/shared method repository class called ExtensionsRegular.

Now, let’s look at how an extension method can help us here.

7 <Extension()> _

8 Public Function FindByID(Of T As PersistLoad)(ByVal list As IEnumerable(Of T), ByVal a_ID As Integer) As T

9 Dim selected = _

10 From b In list _

11 Where b.ID = a_ID _

12 Select b

13

14 If selected.Count > 0 Then

15 Return selected.First()

16 Else

17 Return Nothing

18 End If

19 End Function

Notice with the extension method implementation, we can use the IEnumerable generic interface as the input. We’ll come back to why that’s important in a minute. Inside the implementation of the extension method, we are using a LINQ query that selects from the list (which must implement IEnumerable or it’s generic equivalent IEnumerable) where the ID equals the a_ID parameter we passed in. Notice 1) how similar this is to SQL queries and 2) how natural it looks to the reader in terms of what is actually being done in the code.

Now our calling code looks like:

114 m_CurrentBarcode = m_Barcodes.FindByID(a_BarcodeID)

Because it’s an extension method, the compiler actually allows the method to be called as if it were an instance member method. Notice that the only input parameter is the ID we’re searching for.

Additionally, since we used the IEnumerable(Of T) interface as our input declaration, we can now use this exact same extension method if we were trying to FindByID on basically ANY type (in the .NET framework or otherwise) which implements IEnumerable(Of T), since any IEnumerable type must implement the MoveNext() method.

Advertisements

1 Comment »

  1. […] This is where we find out about Extension Methods. […]

    Pingback by LINQ to Objects: Nested Queries « The Code Slinger — November 20, 2007 @ 11:59 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: