Ahmed El-Halwagy’s Blog

Archive for the ‘LINQ’ Category

A while ago, when I posted my last post on this blog which was titles (Delegates and Events – A Look Back), I stated that it was an introduction to Lambda Expressions. Though it took me more than a month to re-blog again, here i’m continuing the journey on the C# 3.0 language enhancements features. The first thing we will discuss here is anonymous methods, as you know anonymous methods is just a shorthand way for subscribing to events and providing handlers all in one shot. The following code example shows the old way to subscribe to a Click event on a normal System.Windows.Forms.Button object.

code1

This is the very classic way of subscribing to event. You simply need to provide a pre-defined delegate (in this case EventHandler) that points to a function matching a specific signature (in this case returns void and accepts two input parameters an System.Object parameter, and System.EventArgs parameter) . Using anonymous methods, life can be easier. Check out the next code sample.

code2

As you can see here, all I needed to do in order to subscribe to the Click event on the Button object is to simply write my code that handles the event without having to define a whole new function just to handle this event, and also without having to know the event’s delegate signature.

Lambdas

Lambda expressions are another new way in C# 3.0 to substitute delegates in certain places. Now consider the following example, if you have a List<int>  and you want to filter this list and get only all the odd numbers out of it. One solution that might come handy is to use the FindAll method of your generic List<int>. FindAll expects one argument which in fact is of type System.Predicate<T>. System.Predicate<T> is a delegate that can point to any methods returns bool and takes a single argument T. The point is when FindAll was designed it was designed as this(take each item, check it, and then tell me if it should be included in the result set of the call).

The follwoing example illustrates the use of the smart FindAll method, take a look:

code3

As you see here I’ve defined a method called IsOdd that takes a single integer parameter and returns a boolean value indicating whether the passed in parameter is odd or not. I then called the FindAll method on my list of integers (numbers) passing in a new Predicated delegate that points to IsOdd. What is going to happen here is my numbers list will take each element of it and pass it to the IsOdd(the method that the Predicate delegate points to) and check the value returned, if true, then the item will be added to the result set. If false then the item will be ignored. If you run the above code you will get the following result.

code41

Now, what if you don’t want to define this whole IsOdd method that makes a really tiny job here and will not be reused by any other peace of code? Well, you guessed it, use anonymous method syntax like this:
code5

A lambda expression is another handy way for providing an anonymous method. The syntax might seem clumsy at first, but once you get it, you never quit it 😉

code6

What you see here is a lambda expression in action. The FindAll method expects a delegate and this time instead of passing it a delegate or an anonymous method I passed in well, a lambda, a lambda that will operate on one single integer parameter and return the the result of the expression x % 2 != 0.
The thing that most people find uncomfortable about lambdas is that, they can’t pronounce it, yeah, they write it but they can’t pronounce it. Our above example will be pronounce as follows (My only parameter will be processed this way “as what between the {} stats”).
A lambda expression can be in one of two forms; a single line form and a code block form. In our example we wrote a single statement in between two curly brackets, in fact I could have wrote any number of statements as needed. I will show you how lambda expressions can be appeared in a single line form:
code7

Well that’s it for lambdas, any questions or suggestions feel absolutely free to leave a comment.

string name = “Ahmed Halwagy”;

if (name.IsHalwagy())

Console.WriteLine(“Yeap”);

else

Console.WriteLine(“Not halwagy”);

Shocked? .. Cool!
Now I assume that two questions just pumped into your mind:
1- What the heck is that IsHalwagy() method?
2- Would Microsoft ever -for any reason- reshape their string object to add this method?

I will answer your questions from bottom up. Question number 2, the answer is No. Though Microsoft really pursue my own satisfaction, but they never went this far -but I really encourage you to email the C# team and ask them for IsHalwagy() method on the string class(just kidding 🙂 ).

Question number 1, the answer is: It’s my own method. I’ve extended the string class by this IsHalwagy() method, and believe it or not, I didn’t have to use classes from the System.Reflection.Emit namespace, actually the job was much easier(as easy as typing 3 lines of code J ).

Confused! That’s good. Now relax and take a deep breath.
As you know, C# types (classes, interfaces, delegates, structs, enums)once compiled into an assembly, they’re final, meaning that the only way to change them is to have their source code, edit it, and then recompile. However, this is not the case in C# 3.0; in C# 3.0 you can extend any compiled-final- .NET type using a very easy and convenient way through Extension Methods.

Though the usefulness of this capability is extremely obvious in the previous IsHalwagy() example, let’s consider a more useful scenario –at least more useful for you.
<!–[if !supportLineBreakNewLine]–>
<!–[endif]–>

static class IntOperations {

public static bool IsEven(int x) {

return (x % 2) == 0;

}

public static long Factorial(int x) {

if (x <= 1)

return 1;

else

return x * Factorial(x – 1);

}

}

 

In the previous example we have a class called IntOperations this class contains some of the operations than you would need to perform on any integer. The typical use for the methods in this class would be ass follows:

int x = 5;

Console.WriteLine(“The factorial of {0} = {1}”, x,IntOperations.Factorial(x));

Console.WriteLine(IntOperations.IsEven(5));

By using extension methods you can alter the previous example to use the Factorial(int) and the IsEven(int) methods as if they were originally built into the System.Int32 struct. The only change that is required in order to achieve that is to add 8 characters to your methods declaration, as follows:

static class IntOperations {

//Notice the this modifier precedding the parameter declaration.

public static bool IsEven(this int x) {

return (x % 2) == 0;

}

public static long Factorial(this int x) {

if (x <= 1)

return 1;

else

return x * Factorial(x – 1);

}

}
Here all I’ve done is simply adding the “this” modifier before the first parameter of each method declaration. Adding the “this” modifier to the declaration of the int parameter simply instructs the compiler to deal with method as if it was originally built into the System.Int32 type.Voila! that’s it. By doing so you can simply call your methods on any instance of type System.Int32 as if it was originally coded into it:

int x = 5;

Console.WriteLine(“The factorial of {0} = {1}”, x, x.Factorial());

Console.WriteLine(x.IsEven());

Now let’s take alook at what’s really happening behind the scens. If you compile this project and open the assembly using a tool like (ILDASM) you will find that the compiler is invoking the static methods in a very normal manner (i.e. IntOperations.Factorial(x)). What you really saw of x.Factorial() is just some smoke-and-mirror effect. Here’s a part of the IL viewed by IlDASM for this assembly:

 

.method private hidebysig static void Main(string[] args) cil managed

{

.entrypoint

// Code size 44 (0x2c)

.maxstack 3

.locals init ([0] int32 x)

IL_0000: nop

IL_0001: ldc.i4.5

IL_0002: stloc.0

IL_0003: ldstr “The factorial of {0} = {1}”

IL_0008: ldloc.0

IL_0009: box [mscorlib]System.Int32

IL_000e: ldloc.0

IL_000f: call int64 ConsoleApplication3.IntOperations::Factorial(int32)

IL_0014: box [mscorlib]System.Int64

IL_0019: call void [mscorlib]System.Console::WriteLine(string,

object,

object)

IL_001e: nop

IL_001f: ldloc.0

IL_0020: call bool ConsoleApplication3.IntOperations::IsEven(int32)

IL_0025: call void [mscorlib]System.Console::WriteLine(bool)

IL_002a: nop

IL_002b: ret

} // end of method Program::Main

 

 

Ps: the compiler calls the extension methods statically using their clas names.

 

Extension Methods Restrictions:

<!–[if !supportLists]–>1- <!–[endif]–> EExtension methods must be declared in static class, and there for they must be static as well (remember static classes can only contain static methods, and static fields).

<!–[if !supportLists]–>2- <!–[endif]–> Normal object instance methods take precedence over extension methods if they happened to be with the same signuature.

 

Importing namespaces containing types that define Extension Methods:

Namespaces containing the classes that contain extension methods have to imported in order to be able to use the extension methods defined on them.
Let’s take a while discussing this poing, now consider that my IntOperations class is declared inside a namespace called MyEXTNamespace, and the program class containing the main method is declared inside a namespcae called MyAssemblyNamespace. The code will look like the following.
using System;

using System.Linq;

namespace MyAssembly {

class Program {

static void Main(string[] args) {

int x = 5;

Console.WriteLine(“The factorial of {0} = {1}”, x, x.Factorial());

Console.WriteLine(x.IsEven());

}

}

}

namespace MyEXTNamespace {

static class IntOperations {

//Notice the this modifier precedding the parameter declaration.

public static bool IsEven(this int x) {

return (x % 2) == 0;

}

public static long Factorial(this int x) {

if (x <= 1)

return 1;

else

return x * Factorial(x – 1);

}

}

}

If you try to compile this code you will get compile time errors indicating that System.Int32 does not containg a definition fo IsEven() and Factorial(). Can you see it? Can you see the problem?

The problem is you declared your extension methods in MyEXTNamespace and in order to use these methods outside the scope of this namespace you have to import this namespace by adding a using directive to MyEXTNamespace namespace at the top of your file as follows:

using MyEXTNamespace;

Problem Solved!

 

Using Extension Libraries:

Now as you can see it can be very useful if you are able to use your extension methods in many projects as any other .NET library. This is absolutely possible. You can simply move your MyEXTNamespace namespace to another class library project and build this library and simply reference the output assembly from any other .NET project and reuse. Just remember to mark the classes containing the extension methods with the public access modifier in order to be used cross assemblies.

 

A Final Detail:

One last thing you should know about extension methods is that they apply to inheritance concepty i.e. if you extended a parent class with some method, all the derived classes will inherit this method. Take a look at the following example:

public static string ReturnYourParentType(this object o) {

Type t = o.GetType();

if (t.BaseType == null)

return “Don’t have a parent, I’m object”;

return t.BaseType.FullName;

}

 

Here I’ve extended the System.Object class with a method that returns the name of the parent type of any object. Now watch me invoking this method:

 

object o = new object();

Console.WriteLine(o.ReturnYourParentType());

 

int x = 5;

//it applies to int too. because int is an object.

string intParent = x.ReturnYourParentType();

Console.WriteLine(“intParent = {0}”, intParent);

// and applies to string too. again because string is also an object.

string stringParent = “hello”.ReturnYourParentType();

Console.WriteLine(“stringParent = {0}”, stringParent);

 

As you can see here I’ve invoked this method on any thing of type object, and of course in .NET every thing is an object. So because every thing inherits from object, I can call my ReturnYourParentType() on any thing.

 

Here’s a simple problem. Suppose that you have an array of string and you want to filter this array to extract all the items in it that end with the word “Halwagy” the code would more or less look like the following.

string[] names = { “Ahmed Halwagy”, “Mohamed Halwagy”,

“Mohamed Fayad”, “Walid Hamad”,

“Ibrahim Halwagy”,

“Mohamed Shokry”,

“Amr Badawy” };

 

//TODO: Print all the halwagys in the previous list.

//1- Traditional approach

List<string> result = new List<string>();

foreach (string s in names) {

if(s.EndsWith(“Halwagy”))

result.Add(s);

}

foreach (string s in result) Console.WriteLine(s);

I assume that the code listing above is self explanatory, but anyways what’s happening here is you have this string array “names” so you traverse each element in this array and check if it ends with “Halwagy”; if so you add it to your result List<string> to eventually manipulate it as you want.

Now take a look at the next syntax (assuming we have the string array “names”):

//2- New approach (LINQ)

var halwagys = from s in names

where s.EndsWith(“Halwagy”)

select s;

foreach (string s in halwagys) Console.WriteLine(s);

Can you feel it? Can you feel the shift?

Yes it does, it looks like SQL but it’s not SQL.

Now I assume that syntax needs a lot of explanation because it really contains a lot of strange words like var, from, where, select, etc.

So before we digg into an explanation of this statement, let me breifly mention some of the new features in c# 3.0 then we will comeback to this.

First thing we will check now is called Implicitly Typed Local Variables.

C# is a strongly typed, static language which means that you can never declare a variable without identifying its data type; otherwise the compiler will generate an error. For example the statement “x = 20;” will generate a compile time error because you haven’t specified the data type of x explicitly to the compiler so to make that work you had to state that x is an integer like so “int x = 20;”. Now if you tried to change the value of x to another value that is from a different type (e.g. float) like “x = 12.5f” the compiler will generate an error now stating that it failed to implicitly convert from float to int and an explicit conversion is required.

Now take a look at the following:
var x = 20;
what the hek is that? Well appearantly this is not the same as “int x = 20;”. Actually it is the same, when you declare x as int the compiler knows that x is of type System.Int32 and we you declare x as var the compiler will check the value assigned to x, and will automatically infer the type of x based on the type of that value. so in this case the compiler will be able to infer x is of type System.Int32, and this happens automatically.


PS: The type of x will be known in the compile time not in the run time.
<!–[if !supportLineBreakNewLine]–>
<!–[endif]–>

You should know that you can use implicit typing (the var keyword) for any type in the base class library, including arrays, generics, and your custom classes. Take alook at the following examples:
var x = 12.5f; //x is float.
var list = new string[] { “C#”, “LINQ”, “.NET 3.0” }; // list is an array of string
var y = list.Length; //y is int.
//using implicit typing in foreach loop.
foreach(var tech in list) { //tech is string
Console.WriteLine(tech);
}
Restrictions on Implicit Typing:
1- Implicitly typed variables must be be locals (in a method or a property scope).
2- Local variables declared using var keyword must be assigned an initial value at the time of declaration, and this value can’t be null. (because, as you may recall, the compiler will infer the type through that value. So the compiler won’t be able to know the sort of type in memory, that the variable will point to by only null).
3- Like any normal strongly typed variable, implicitly typed variables can’t hold a value of a different data type than its original one.


Here’s a code example with the restrictions of the var keyword:
class UnCompilable {

//Error: the contextual keyword var may only appear within local variable declaration

var x = 20;

 

void DoSomething() {

//Error: Implicitly-typed local variables must be initialized.

var y;

//Error: can’t assign <null> to an implicitly-typed local variable.

var yy = null;

var onlyString = “Ahmed”;

onlyString = “This is ok”;

//Error: can’t implicitly convert type int to string. remeber, it’s a string

onlyString = 2;

}

}

 

The rest of the features will be posted soon.


 

 


Calendar

August 2017
S M T W T F S
« Nov    
 12345
6789101112
13141516171819
20212223242526
2728293031  

Categories

Delicious

Recent Twitter Updates

Error: Twitter did not respond. Please wait a few minutes and refresh this page.