Thursday, 9 August 2012

C#: Anonymous types

My previous post on Extension methods talked about how they were implemented to allow LINQ to operate. Another requirement for LINQ is Anonymous types.

Anonymous types are real types - the actual name of the type is not known (at least to you as the developer). The name of the type will be known to the compiler but you will not be able to access it. In an anonymous type you will define properties, which will be read-only and the type of each property will be inferred from the data put into it. Let's look at an example
var book = new { BookName = "Twilight", Author = "Stephenie Meyer", ISBN = "0316160172" };

Console.WriteLine("Name {0}", book.BookName);
Console.WriteLine("Author {0}", book.Author);
Console.WriteLine("ISBN {0}", book.ISBN);

Console.WriteLine(book);

Console.WriteLine(book.GetType());
Here we create a variable called book which is output using the properties (BookName, Author and ISBN). We also output the variable and the type that it is called.

The output of book (using the ToString() method) is useful for debugging. Finally the type name is not useful - but internally this is what the compiler will store it as.

Looking at the code we are using this var keyword. A variable declared with the var keyword is still strongly typed - but the compiler will determine the type. If we have a List and want to loop through it we could use
List<string> inputs = new List<string> { "one", "two", "three", "four", "five" };

foreach (var input in inputs)
    Console.WriteLine(input);
Here the use of the var keyword is allowed - but the type is known. I have begun to see developers using the var keyword all the time - rather than in this case use the string keyword. You know what the type is - why make it difficult for other developers reading your code! Just because you can do something doesn't mean you have to do it.

But in our example to create an instance of our anonymous type we used var. We are forced to use var as we don't know what type we have.

In LINQ we generally don't know what type we are creating. Let's look at the LINQ example to convert the strings to upper case. I am using var here - but what type is being returned?
var outputs = from s in inputs
              select s.ToUpper();

foreach (var output in outputs)
    Console.WriteLine(output);
The output is IEnumerable<string> - this is not an anonymous type. We know that when the LINQ query is executed (when it is first accessed) it is going to return something of this type. But, by convention we use the var keyword.

Another common thing to do is the following
var outputs = (from s in inputs
              select s.ToUpper()).ToList();
This forces immediate execution - but the type is known, it is List<string>. But, again, by convention we use the var keyword.

Here is an example with an anonymous type.
var infos = from s in inputs
            select new { Original = s, Upper = s.ToUpper(), 
                         Lower = s.ToLower(), Length = s.Length };

foreach (var info in infos)
    Console.WriteLine(info);
In this example the output will be an anonymous type - with four properties (Original, Upper, Lower and Length). In this case we are forced to use the var keyword. The output from this looks like

As I said earlier a variable declared with the var keyword is still strongly typed. You will find that the intellisense works.

Sunday, 5 August 2012

C#: Extension methods

Extension methods were introduced into .NET 3.5 and allows you to augment functionality to a class without changing the class. Sounds not quite right though. What you actually do is write functionality that operates on an instance of a class using the public methods/fields/properties of that class and looks like you have added functionality.

We define an extension method as a static method within a static class. The first parameter of the method identifies which class you are augmenting which is prefixed with the this keyword.

Let's create a simple extension method which operates on the long type. This method will return a bool if the number is PanDigital. A PanDigital is a number which amongst it's significant digits the number is used at least once, for example the numbers 1234567890 and 13402456789 are pandigital.

The signature of this method (within out static class) will be
public static bool IsPanDigital(this long number)
The main difference between this method and normal methods is the use of the this keyword before the type of the first parameter. Once this method is written the method could be used as
long number = 1234567890;
bool pd = number.IsPanDigital();
The full method could look like this
public static class PanDigitalExtentionMethod
{
    public static bool IsPanDigital(this long number)
    {
        string strNumber = Convert.ToString(number);

        for (int i = 0; i < 10; i++)
        {
            if (!strNumber.Contains(i.ToString()))
                return false;
        }
        return true;
    }
}
When using this you add any correct references and using statement or put all your extension methods in one namespace (normally in one directory).

The method you write looks as if there is no difference between calling the extension method and any other method that is defined in the class.

Where is this used?

I first (explicitly) came across this when developing a MVC (web) application. Common practice is to create "Html Helpers", so for example with the following extension method
namespace Helpers
{
  public static class HtmlHelpers
  {
    public static string OrdinalSuffix(this HtmlHelper helper, int input)
    {
      if (input == 0)
          return "";
      else
      {
          //can handle negative numbers (-1st, -12th, -21st)
          int last2Digits = Math.Abs(input % 100);
          int lastDigit = last2Digits % 10;

          //the only nonconforming set is numbers ending in 
          //   <...eleventh, ...twelfth, ...thirteenth> 
          return input.ToString() + 
              "thstndrd".Substring((last2Digits > 10 && last2Digits < 14) 
                                            || lastDigit > 3 ? 0 : lastDigit * 2, 2);
       }
    }
  }
}
This method will take an integer (e.g. 2) and return a string with the number followed by it's ordinal suffix (e.g. 2nd). You could then use this from within a View. For example, within Razor you could have code such as
<p>
<%: Html.OrdinalSuffix(history.Position) %>
</p>
In a MVC application you would normally edit the web.config file to add the namespace for the Helpers (under the system.web/pages/namespaces node) - thus making it available in all your pages without you having to add an explicit using clause.

Now, I said MVC was the first time I encountered extension methods - in fact, I said the first time I explicitly encountered them. The .NET development team just didn't decide to add this functionality. Whilst it looks cool to use - I have reservations about using extension methods as we have used them above. If I were looking at some code and I saw a method .IsPanDigital then I would need to make the jump that this was an extension method. Although, if you put the mouse over the call (in Visual Studio) it will tell you that it is an extension method.

So why were extension methods added - to help support LINQ. You may well have used them without knowing about it. Let's take an example where we want to retrieve from a List the strings that are three characters in length. We will work with this list
List<string> inputs = new List<string> { "one", "two", "three", "four", "five" };
Code to do this with LINQ might be
var threeLinq = from r in inputs
                where r.Length == 3
                select r;
foreach (var result in threeLinq)
    Console.WriteLine(result);
Running this will give the outputs "one" and "two". But underneath this code is what is being run
var three = inputs.Where(s => s.Length == 3);
foreach (var result in three)
    Console.WriteLine(result);
The function Where is an extension method (of string). Putting our mouse over the Where will show you.

Another quick example
var ordered = inputs.OrderByDescending(i => i);
foreach (var result in ordered)
    Console.WriteLine(result);

var orderedLinq = from r in inputs
                  orderby r descending
                  select r;
foreach (var result in orderedLinq)
    Console.WriteLine(result);
This example shows using the OrderByDescending extension method - in Linq you use the orderby and descending keywords.

In both the LINQ examples we are using the select keyword. Let's look at these - we will retrieve our output in upper case
var three = inputs.Where(s => s.Length == 3).Select(s => s.ToUpper());
foreach (var result in three)
    Console.WriteLine(result);

Console.WriteLine("---");
var threeLinq = from r in inputs
                where r.Length == 3
                select r.ToUpper();
foreach (var result in threeLinq)
    Console.WriteLine(result);

In LINQ using select r.ToUpper() translates into using the Select extension method.