Arriving to LINQ

18 01 2008

As everybody know, LINQ is one of the new feature in .NET 3.5 framework

I thought let me take you a small ride on how I arrived in using LINQ :D

I will take you from the common approach and then a step ahead and finally arrive to LINQ

(I am taking very very generic example to showcase this)

Problem : Given a array which has some words, find the words that end with letter “s”

1) Normal old style approach

Normal method would be just to write a function, pass the array of strings and return back our result

ArrayList arrList;
String[] strName = { "this", "is", "at" };

//plain old method
Console.WriteLine("Using plain old method - Calling a function");
arrList=OldMethod(strName);
for(int i=0;i<arrList.Count;i++)
{
    Console.WriteLine("String = {0}",arrList[i]);
}
arrList.Clear();

And our OldMethod function is as follows,

static ArrayList OldMethod(string[] strName)
{
    ArrayList arrList = new System.Collections.ArrayList();

    for (int i = 0; i < strName.Length; i++)
    {
        string name = strName[i];

        if (name.EndsWith("s"))
        {
            arrList.Add(name);
        }
    }

    return arrList;
}

2) Using Delegates

Now, you feel like providing a delegate and we shift to Named methods now

1) We declare a delegate

internal delegate ArrayList MyDelegate(string[] strName);

2) Our function

static ArrayList UsingNamedMethods(string[] strName)
{
    ArrayList arrList = new System.Collections.ArrayList();

    for (int i = 0; i < strName.Length; i++)
    {
        string name = strName[i];

        if (name.EndsWith("s"))
        {
            arrList.Add(name);
        }
    }

    return arrList;
}

3) Assign the function to the delegate object

//using named methods
Console.WriteLine("Using Named Methods - Using Delegates");
MyDelegate MyFunction = UsingNamedMethods;

4) Invoke the delegate

arrList=MyFunction(strName);

5) Display our results

for (int i = 0; i < arrList.Count; i++)
{
    Console.WriteLine("String = {0}", arrList[i]);
}
arrList.Clear();

3) Using Anonymous Methods

Now, we can use Anonymous Methods in C# and overcome some of the complexities that we have in Named Methods. With Anonymous methods, we have access to local variables too.

Again we have a delegate and then use that delegate object to create our anonymous method

internal delegate void AnonymousDelegate();

You can see the change in previous delegate declaration and the one above.As we have access to local variables, we need not pass or return, and manipulate things locally itself. So we don’t create a new method for our delegate.

//using anonymous methods
Console.WriteLine("Using Anonymous Methods - Welcome to C# 3.0");
AnonymousDelegate AnonymousMethod = delegate()
                            {
                                foreach(string s in strName)
                                {
                                    if (s.EndsWith("s"))
                                        arrList.Add(s);
                                }
                            };
AnonymousMethod();
for (int i = 0; i < arrList.Count; i++)
{
    Console.WriteLine("String = {0}", arrList[i]);
}
arrList.Clear();

4) Using Generic Function Delegates

Still, we can eliminate delegate declaration and instantiation with the generic Function delegates that are available

//using generic function delegates
Console.WriteLine("Using Generic Function Delegates");
Func<ArrayList> FunctionGenericDeletgateCall = delegate()
                                        {
                                            foreach (string word in strName)
                                            {
                                                if (word.EndsWith("s"))
                                                    arrList.Add(word);
                                            }

                                            return arrList;
                                        };
arrList=FunctionGenericDeletgateCall();
foreach(string word in arrList)
{
    Console.WriteLine("String = {0}",word);
}
arrList.Clear();

Certainly that doesn’t look that good. So what do we have next?

5) Using Extension Methods

Yes, Extension Methods! This makes life easier for others who start using your framework or API or Program. Extension Methods enables you to add “your own” methods to the existing types. So we will add a method that returns us the words ending with “s” to the data type string[]

First, Extension methods should be always static methods inside a static class. Let us create them

public static class ExtensionMethods
{
    public static ArrayList ContainsMyCharacter(this string[] strName)
    {
        ArrayList arrList = new System.Collections.ArrayList();

        for (int i = 0; i < strName.Length; i++)
        {
            string name = strName[i];

            if (name.EndsWith("s"))
            {
                arrList.Add(name);
            }
        }

        return arrList;
    }

}

Next, we just use it as how you use inbuilt methods;)

//using Extension Methods
Console.WriteLine("Using Extension Methods");
arrList=strName.ContainsMyCharacter();
foreach (string word in arrList)
{
    Console.WriteLine("String = {0}", word);
}
arrList.Clear();

This has made our life easier than our earlier methods :D

6) Using Generic LINQ (System.Linq) with Lamda Expressions

Now we get into the usage of Lambda Expressions and the Generic LINQ. Well, we haven’t still arrived at the most easiest way of programming ;)

We can use System.Linq.Enumerable to make the above process a bit simpler

//using LINQ Generic Methods
Console.WriteLine("Using Generic Linq with Lambda Expressions");
IEnumerable<string> collection=System.Linq.Enumerable.Where(strName, s => s.EndsWith("s"));
foreach (string word in collection)
{
    Console.WriteLine("String = {0}", word);
}

7) Using LINQ with Lambda Expressions

So, how can we make the above process even more simpler? :D

With C# 3.0 and LINQ and Extension Methods, the query operators are implemented as extension methods ;)

Yes, you guessed it right, we can directly query on the variable strName

//using LINQ Lambda Expressions
Console.WriteLine("Finally - Here is LINQ with Lambada expressions without Generic Functions");
collection = strName.Where(s => s.EndsWith("s"));
foreach (string word in collection)
{
    Console.WriteLine("String = {0}", word);
}

8 ) Finally, last but not the least – Using Queries

You can also query instead of directly using the extended query operators methods like Where – the one we used above

//using LINQ Query
Console.WriteLine("Using LINQ Queries");
var query = (from s in strName
              where s.EndsWith("s")
              select s);
foreach (string word in query)
{
    Console.WriteLine("String = {0}", word);
}

If you look into Reflector, the last 3 methods will be interpreted as same. So using any of them would be fine. Only that, using the Generic LINQ as in 6 will result to 7 when compiled, so we could directly use method 7

You can download the source code of the above application here

8)





.NET Source Code (not all, but few) released!

18 01 2008

vs08_v_rgb_web.jpg

Yes, as promised earlier, here comes the .NET Source Code :)

Read here on how to enable source code debugging from the person who made this possible :D

And for a screencast, Daniel Moth has an excellent screencast. Watch it here 

One notable change is in the licensing of the source code which can be read here at Scott Gu’s blog

Here is the excerpt  from the above link,

The .NET Framework source is being released under a read-only reference license. When we announced that we were releasing the source back in October, some people had concerns about the potential impact of their viewing the source. To help clarify and address these concerns, we made a small change to the license to specifically call out that the license does not apply to users developing software for a non-Windows platform that has “the same or substantially the same features or functionality” as the .NET Framework. If the software you are developing is for Windows platforms, you can look at the code, even if that software has “the same or substantially the same features or functionality” as the .NET Framework.

:)








Follow

Get every new post delivered to your Inbox.