#813 – Defining an Extension Method for an Enumerated Type

In addition to other types, you can extend the functionality of an enumerated type using extension methods.

Below is an extension method that extends the DayOfWeek enumerated type.

        public static string Activity(this DayOfWeek day)
        {
            string activity = "";

            switch (day)
            {
                case DayOfWeek.Sunday:
                    activity = "Reading paper";
                    break;
                case DayOfWeek.Monday:
                    activity = "Grumbling";
                    break;
                case DayOfWeek.Tuesday:
                    activity = "Eating tacos";
                    break;
                case DayOfWeek.Wednesday:
                    activity = "Reading";
                    break;
                case DayOfWeek.Thursday:
                    activity = "Cursing";
                    break;
                case DayOfWeek.Friday:
                    activity = "Celebrating";
                    break;
                case DayOfWeek.Saturday:
                    activity = "Hiking";
                    break;
            }

            return activity;
        }
    }

We can now call the Activity method on any variable or constant whose type is DayOfWeek.

            DayOfWeek today = DayOfWeek.Thursday;
            Console.WriteLine(today.Activity());

            Console.WriteLine(DayOfWeek.Friday.Activity());

813-001

#812 – Defining an Extension Method for a Value Type

You can define an extension method against any type, including both reference types and value types.

Here’s an example of an extension method that adds functionality to the int (System.Int32) type.

    static class MyExtensions
    {
        public static int Triple(this int i)
        {
            return i * 3;
        }
    }

The Triple method now acts as an instance method that we can invoke on any variable of type int or even on an integer constant.

            int i = 123;
            Console.WriteLine(i.Triple());

            Console.WriteLine(12.Triple());

812-001

#811 – Extension Methods Can Only Access Public Members of Class

When you write an extension method to extend the behavior of an existing class, the code in your extension method has access only to the public members of the class being extended.  Even though the code that you are writing acts as a new instance method on the class, the code within your method has no special access to the members of the class beyond its public members.

#810 – Where Extension Methods Came From

Extension methods were introduced into the C# language as part of version 3.0 of the language, introduced in November of 2007.  C# 3.0 was part of the same release that included version 3.5 of the .NET Framework.

Extension methods are a language mechanism that can be used in a variety of circumstances.  They were included in the language, however, to help support the features of LINQ (Language Integrated Query), which was also introduced in November, 2007, as part of .NET Framework 3.5.

LINQ includes a large number of extension methods that extend the existing System.Collections.Generic.IEnumerable<T> class, which was part of .NET Framework 2.0.  Adding this functionality by way of extension methods allowed LINQ to operate on standard collections, rather than introducing a new LINQ-specific collection class.

810-001

#809 – Extension Method Signatures Shouldn’t Match Class Methods

The idea of writing an extension method is to create a method that can be invoked in the same way as one of the instance methods of a class.  You can’t override an existing instance method using an extension method, but only add new methods.

If you author an extension method that has the exact same signature as an existing instance method in the class, the compiler won’t complain about your new method.  But if you try invoking the method, the original instance method will be called, rather than your extension method.

    static class StringExtensions
    {
        // Will never get called
        public static int CompareTo(this string s1, string s2)
        {
            return 0;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string s = "Pan Am";
            int n = s.CompareTo("KLM");    // Original CompareTo method called

            Console.ReadLine();
        }
    }

#808 – Adding Parameters to an Extension Method

When you define an extension method, the first parameter of your method represents the instance that you want the method to act upon.  You can, however, add additional parameters.

An extension method that acts on a string, for example, would have string as the first parameter and then, optionally, some other parameters.

        public static string Decorate(this string s, string frontDec, string backDec)
        {
            return frontDec + " " + s + " " + backDec;
        }

When you invoke the method, you pass in these additional parameters.

            // Using the extension method
            string s = "Salk announces polio vaccine";
            string dec = s.Decorate("<<==", "==>>");
            Console.WriteLine(dec);

808-002

Notice that Intellisense now lists the new extension method as an option for the string type and correctly lists two parameters.
808-001

#807 – Defining and Using an Extension Method

An extension method is a method that you define to extend an existing class without having to modify or inherit from the existing class.  The new method behaves as if it was defined as an instance method of the original class.

For example, you might define a Decorate() method that extends the System.String class.

To define an extension method:

  • Define it in a static class, as a static function
  • The 1st parameter must be of the type that you are extending and must include the this keyword on the parameter
    static class StringExtensions
    {
        public static string Decorate(this string s)
        {
            return "** " + s + " **";
        }
    }

You can now use the extension method as if it was an instance method on the System.String class.

            string s = "Fire at the triangle factory";
            Console.WriteLine(s.Decorate());

807-001