Another Use for Extension Methods

by Chad 24. November 2009 11:55

I’m a big fan of Extension Methods and today I found another use for them while discussing the Managed Extensibility Framework with my friend Matt Lowrance. I previously thought that there was little reason to add extension methods to types that you control the source code for. The idea being that if you have access to the source code, it’s better to extend the type directly since you’ll have access to private state.

DiagramToday’s epiphany is that in a loosely coupled system, Extension Methods can be used to hide that loose coupling.  For example consider the diagram to the right. I have an ObjectContainer class that is unaware of my CustomObject class. Additionally, CustomObject may be completely unaware of ObjectContainer.

Using an extension method, I can call GetCustomObjects() on an instance of ObjectContainer and receive an array of CustomObject. With this syntax, it appears that the ObjectContainer is aware of CustomObject, but in reality it isn’t. The only type that is tightly coupled is the static ExtensionMethods class that must be aware of both types.

Tags: ,

.NET-Basics

Simplifying LINQ - Extension Methods

by Chad 19. April 2009 11:09

Introduction

Welcome back for part three in my 'Simplifying LINQ' series!  This series of blog posts is intended to simplify the .NET 3.0 language features that make LINQ possible.  I try to do so by showing how the language features have evolved with each framework release.  Hopefully you've been following along, but if not - it's no big deal. If you'd like to catch up you can read about Lambda Expression or Object Initialization, Type Inference, and Anonymous Types.

This post discusses one of my favorite (second only to Generics) .NET language features - Extension Methods.  I'm a fan of extension methods because they enable you to write cleaner more useful code.  With extension methods you can extend the behavior of a class or interface by invoking static methods using instance method syntax.  

I digress...

I'd like to talk briefly about State and Behavior to clarify the limitations of Extension Methods.  State is the instance data that an object encapsulates and behavior is the things that an object does to manipulate it's or other objects' state.  With extension methods you are adding behavior to an object, but cannot add state to that object.  Keep this in mind when learning about extension methods because you may have a natural tendancy to try to add state members.  Additionally, extension methods can only access public members.

For example, if you have an existing Person class with two properties: FirstName and LastName.  You CAN add a GetFullName() method because the person class publicly exposes FirstName and LastName data. You CANNOT add GetDateOfBirth() or SetDateOfBirth(DateTime) methods because the person object doesn't publicly expose a DateTime variable to store that data.

Before .NET 3.0 - Static Methods

Static methods have been around for a long time and you are probably aware of them.  Static methods are nice for utility code because you can call the method without instantiating an instance of the defining class. Static methods can be limiting though because they are syntactically bulky - both to write and to read. For example, the code snippet below uses static methods to increment an integer variable 'i' then convert it to it's textual equivalent.  Notice that the expression is read from the inside out - starting with 'i' then 'Plus1()' then 'ToWord()'. Imagine if this statment were more complex. Nesting more than three or four static method calls would become pretty unmanageable.

string line = IntExtender.ToWord(IntExtender.Plus1(i));

The code for the static methods Plus1(int) and ToWord(int) is below. This code should look familiar and is the basis for extension methods.

public class IntExtender

    {

        public static string ToWord(int value)

        {

            switch (value)

            {

                case 0:

                    return "Zero";

                case 1:

                    return "One";

                case 2:

                    return "Two";

                ...

            }

        }

        public static int Plus1(int value)

        {

            return value + 1;

        }

    }

.NET 3.0 Introduces Extension Methods

With a few minor tweaks to our IntExtender class we can clean up the first statement by making the static methods extension methods. Extension methods use the same syntax as static methods with the addition of two more requirements (which I've emphasized with bolding and underlining.)

 

  • The defining class must be marked static (meaning it can only contain static members)
  • The first argument of the static method must include the 'this' keyword to indicate that that parameter is the type that is being extended. For example, ToWord() and Plus1() extend the 'int' type.

 

    // Extension methods must be defined in a static class

    public static class IntExtender

    {

        // To create an extension method, the first parameter must use the "this"

        // keyword and specify the type that is being extended.

        public static string ToWord(this int value)

        {

            switch (value)

            {

                case 0:

                    return "Zero";

                case 1:

                    return "One";

                case 2:

                    return "Two";

  ;              ...

            }

        }

        public static int Plus1(this int value)

        {

            return value + 1;

        }

    }

Now that we've updated the IntExtender class we can clean up the first statement that we looked at.  The first thing that we need to do is make sure that the namespace that contains the IntExtender class is in scope. You do this with a using statement (Imports in VB.)  If IntExtender is in the same namespace it should already be visible. 

string line = i.Plus1().ToWord();

Notice that the new code using extension methods now reads left to right: 'i' then 'Plus1()' then 'ToWord()'.  With this syntax, you could add many more extension method calls before the code became unreadable.  You should also notice that we do not have to pass in the first 'this' argument to the extension method - the compiler knows to pass in the variable that is being extended.

Final thoughts...

Extension methods are used extensively in LINQ.  The LINQ libraries provide many extension methods to the IEnumerable and IEnumerable<> interfaces. Using a pattern known as method chaining (Extension methods that return the same type that they extend) data can be filtered and manipulated easily using clean syntax such as 'myData.Where(...).OrderBy(...).First(...);'

Extension methods have many uses outside of LINQ. They can be used to extend base class library types, interfaces, and classes that cannot be inherited from. In a future post, I'd like to show some examples of how I've used extension methods to clean up my code. Be sure to play with them and tell me how you've used extension methods in your projects!

Tags: ,

Simplifying-LINQ

Language Enhancements Presentation Materials

by Chad 25. March 2009 18:25

I've uploaded the demo code and slides from my 'Language Enhancements That Make LINQ Possible' presentation at last night's Springfield .NET Users' Group meeting.  Thank you to everyone who attended; I enjoyed the questions and feedback. If you have any problems with the download or questions about the samples, leave me a message in the comments. Enjoy!

SGFUG_LanguageEnhancements.zip (70.19 kb)

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

About the author

Chad

Meeeee!!!

Hi, my name is Chad Boschert and I'm a software developer in Springfield, Missouri. I've been developing .NET applications in C# since 2002.

Recent Comments

Comment RSS

Calendar

<<  April 2014  >>
MoTuWeThFrSaSu
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar