by
kirupa | 1 June 2009
When creating an application,
you declare variables and use objects that all have a Type
associated with them. Types you probably use commonly
include int,
double,
string,
Array, etc. One common type that I like to use
often is a List. As with any
object you use in .NET, you have access to all methods and
properties the object exposes.
For example, any object you declare of type
List comes
with a sizable amount of methods and properties that allow you to do
things on the List or the data stored inside them:
These methods and properties
live either on the List itself, or they live on the various
classes that make up your List. Think of this is an
exclusive club that members or only members' friends can
gain access to.
What if you had an existing
application that used the List type a lot and you wanted to add the
ability to, let's say, remove duplicate values from your
list. What are your options for solving this dilemma?
You have several options. One option is to create your own
type that extends List, and in this type, have your custom method
that removes duplicate values. Another option is to simply create a
separate static method that takes a List as its argument and
returns a filtered version of the same List with all
duplicate values removed.
Both of these options have
their advantages and disadvantages, but you now have another
way of solving this problem. You can use what are known as extension methods
and have
your custom method that removes duplicates appear as a
member of the List type itself:
The exclusive club is still
very exclusive, but you were now able to sneak in by
following a regular member indoor. The RemoveDuplicates
method is kind of like that person who snuck in. It is not a
method your List type (or types that List derives from)
provide, but notice that I am able to use it almost as if it
were. In this article, I will describe the magic that is an
extension method and possibly teach you how to sneak into
exclusive, cool establishments.
To see an extension method in action, download my
example from the following link and extract the contents of
the Zip file into some location:
Once you have downloaded and
extracted these files, open the ExtensionMethodsSample.sln
in Visual Studio. This isn't a particularly visual sample
where hitting F5 will show you something useful. Instead,
everything relevant is in code with no UI backing it, so
open Window1.xaml.cs instead.
Look at the code in your
MainWindow class where the example lives:
- public
partial
class
MainWindow
:
Window
- {
-
public
MainWindow()
- {
-
//
Required to initialize variables
-
InitializeComponent();
-
- List<string>
input
=
new
List<string>();
- input.Add("There");
- input.Add("Here");
- input.Add("Sneer");
- input.Add("There");
- input.Add("Near");
- input.Add("Meer");
- input.Add("Here");
-
- List<string>
result
=
input.RemoveDuplicates();
- }
- }
What I am doing is declaring a
new List object named input and adding some text to it.
Notice that the text I am adding is not unique. The words
There and Here
are being duplicated. What I want to do is remove those
duplicated values. In the past, if I wanted these duplicate
values removed, I would do something as described in this
tutorial.
In the world of extension
methods, though, all I needed to do is as follows where I
call a RemoveDuplicates
method on my input List
object itself:
- List<string>
result
= input.RemoveDuplicates();
This is possible thanks to
extension methods, and while creating your own
extension method is not quite as easy as using one, it is
actually not particularly difficult either. Let's look at how to create
this RemoveDuplicates extension method that works on your
List.
Creating an extension method
is not very hard, and the tricky part is just remembering
the syntax for doing all of this. Below is the code for my
RemoveDuplicates extension method:
- public
static
class
Extensions
- {
- public
static
List<T>
RemoveDuplicates<T>(this
List<T>
input)
- {
- Dictionary<T,
int>
uniqueStore
=
new
Dictionary<T,
int>();
- List<T>
finalList
=
new
List<T>();
-
- foreach
(T
currValue
in
input)
- {
- if
(!uniqueStore.ContainsKey(currValue))
- {
- uniqueStore.Add(currValue,
0);
- finalList.Add(currValue);
- }
- }
- return
finalList;
- }
- }
-
- public
partial
class
MainPage
:
UserControl
- {
-
public
MainPage()
- {
-
//
Required to initialize variables
-
InitializeComponent();
-
-
List<string>
input
=
new
List<string>();
-
input.Add("There");
-
input.Add("Here");
-
input.Add("Sneer");
-
input.Add("There");
-
input.Add("Near");
-
input.Add("Meer");
-
input.Add("Here");
-
-
List<string>
result
=
input.RemoveDuplicates();
- }
- }
Let's look at the code in
greater detail by starting at the very top:
- public
static
class
Extensions
Your extension method has to
live in a class that is static and non-generic. It would be
nice if you could just have your extension method be
included in the class that defines your MainPage your
usercontrol, but unfortunately you cannot do that.
- public
static
List<T>
RemoveDuplicates<T>(this
List<T>
input)
In this line, you actually
declare your extension method called RemoveDuplicates that
returns a List when called. Notice that your extension
method is public,
static, and takes a
reference to the class it is extending (List<T>)
as an argument.
- List<string>
input
= new
List<string>();
- input.Add("There");
- input.Add("Here");
- input.Add("Sneer");
- input.Add("There");
- input.Add("Near");
- input.Add("Meer");
- input.Add("Here");
-
- List<string>
result
= input.RemoveDuplicates();
The above code lives in my
MainPage class, and it is here that I actually call my
RemoveDuplicates extension method. To reiterate what I
mentioned in my introduction, notice that I am calling
RemoveDuplicates almost as if it where a method that was
native to the List class itself.
That is really all there is to using extension
methods in both WPF and Silverlight. They are a
great way for you to enhance an existing type with
more functionality without having to extend the type
or perform other clever acrobatics.
Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!
|