33
Revisiting C# Anoop Madhusudanan : http://amazedsaint.com This book is intended to be a value adding reading material for beginner to intermediate C# programmers. It may also be used for accelerating the learning about new and upcoming features in C#, and also to get an introduction about new libraries in .NET. You may find random articles and alternate perspectives related to various aspects of C# - ranging from delegates, lambdas, fluent interfaces, dynamic features etc. with practical examples.

Revisting C# V1.0

Embed Size (px)

DESCRIPTION

This book is intended to be a value adding reading material for beginner to intermediate C# programmers. It may also be used for accelerating the learning about new and upcoming features in C#, and also to get an introduction about new libraries in .NET. You may find random articles and alternate perspectives related to various aspects of C# - ranging from delegates, lambdas, fluent interfaces, dynamic features etc. with practical examples.

Citation preview

Page 1: Revisting C# V1.0

Revisiting C#

Anoop Madhusudanan :

http://amazedsaint.com

This book is intended to be a value adding reading material

for beginner to intermediate C# programmers. It may also

be used for accelerating the learning about new and

upcoming features in C#, and also to get an introduction

about new libraries in .NET. You may find random articles

and alternate perspectives related to various aspects of C# -

ranging from delegates, lambdas, fluent interfaces, dynamic

features etc. with practical examples.

Page 2: Revisting C# V1.0

Revisiting C# 1

Contents

Contents ........................................................................................................................................................ 1

Revisiting Delegates, Anonymous Methods and Lambdas ........................................................................... 2

Creating Fluent Interfaces In C# .................................................................................................................... 6

Anonymous Types in C# and Object Initializer Syntax ................................................................................ 10

Type Inference in Generic Methods ........................................................................................................... 12

The Case Of switch-case in C#. .................................................................................................................... 13

C# 4.0 dynamic Features – Under the hood ............................................................................................... 15

Mr ExpandoObject in C# 4.0 ....................................................................................................................... 23

C# Enums – A Second Look ......................................................................................................................... 25

Top 5 Developer Mistakes C# Developers Should Not Commit.................................................................. 27

4 .NET 4.0 Libraries You Should Know About ............................................................................................. 31

Further Reading .......................................................................................................................................... 32

Page 3: Revisting C# V1.0

Revisiting C# 2

Revisiting Delegates, Anonymous Methods and Lambdas

Let us explore few concepts about Delegates, Anonymous methods, Lambdas and Expression Trees.

This is an introductory post, and I‟ll follow up with more posts. These code examples are pretty

simple, you can fire up a C# Console application in Visual Studio and try these examples if you are

interested.

Delegates

We know that a delegate is a type that can reference a method. For example, consider this example to

define a delegate and create a delegate instance.

1. //Example 1 - Creating a delegate instance using Named method 2. 3. public delegate int BinaryOperationDelegate(int x,int y); 4. 5. class Program 6. { 7. static void Main(string[] args) 8. { 9. //Create a delegate instance using named method 10. var add = new BinaryOperationDelegate(AddOperation); 11. int result = add(20, 30); 12. Console.WriteLine(result); 13. } 14. 15. static int AddOperation(int x,int y) 16. { 17. return x+y; 18. } 19. }

The above code will give you an output of 50, no doubt, right ? :)

Anonymous Methods

Now, you may know that with C# 2.0, we can use anonymous methods to create a delegate instance

without a named method. Let us re-write the above implementation leveraging an anon method.

Instead of the method name, you‟ve to use the „delegate‟ keyword. Also, note that there is no need to

specify a return type – because the return type will be inferred from the delegate signature.

1. //Example 2 - Creating a delegate instance using Anon method 2. 3. public delegate int BinaryOperationDelegate(int x,int y); 4. 5. class Program 6. { 7. static void Main(string[] args) 8. { 9. //Create a delegate instance using anon method 10. BinaryOperationDelegate add=

Page 4: Revisting C# V1.0

Revisiting C# 3

11. delegate(int a, int b) { return a+b;} ; 12. int result = add(20, 30); 13. Console.WriteLine(result); 14. } 15. 16. }

Lambdas

And of course, you might also know that with C# 3.0, you can use Lambdas for producing anonymous

methods. A lamda expression is exactly a function, that can contain statements and expressions. Here

is the equivalent of above code, still shortened using a lambda

1. 2. //Example 3 - Creating a delegate instance using statement lambda 3. 4. public delegate int BinaryOperationDelegate(int x, int y); 5. class Program 6. { 7. static void Main(string[] args) 8. { 9. //Create a delegate instance using a statement lambda 10. BinaryOperationDelegate add =(a,b)=>{ 11. //this statement block can contain 12. //multiple statements 13. return a+b; 14. }; 15. 16. int result = add(20, 30); 17. Console.WriteLine(result); 18. } 19. 20. 21. }

In the above example, note the lambda syntax that replaces the anon method syntax in example 2

1. (a,b)=>{ 2. return a+b; 3. };

The types of input parameters a and b and the return type will be inferred correctly by the compiler,

based on the context. How ever, on scenarios where the compiler can't infer the type directly, you can

provide that explicitly. Like this.

BinaryOperationDelegate add =(int a, int b)=>{ return a+b; };

There are basically two type of lambdas - Statement Lamdas and Expression Lambdas. The above

example shows a statement lambda, as the right hand expression is inside a statement block, of the

form

(param1, param2)=> { statement1; statement2; } ;

If you won't have input parameters, you may use the syntax

Page 5: Revisting C# V1.0

Revisiting C# 4

()=> { statement1; statement2; } ;

=> simply means 'goes to', and you may say that the input parameters goes to the statements (for

some processing) :)

Statement Lambdas And Expression Lambdas

We‟ve seen how to create Statement lambdas in the above example. Now, let us explore a bit about

Expression Lambdas (or single line lambdas). The syntax is similar to statement lambdas, but for

expression lambdas, the right hand expression shouldnot be inside a statement block { }. Instead of

having statements on the right side, an Expression Lambda can have a single line expression on the

right hand side. Here is the simple example, with out the statement block.

1. public delegate int BinaryOperationDelegate(int x, int y); 2. 3. class Program 4. { 5. static void Main(string[] args) 6. { 7. //Expression Lambda 8. BinaryOperationDelegate add =(a, b)=>a+b; 9. int result = add(20, 30); 10. 11. Console.WriteLine(result); 12. } 13. }

The above code produces the same result as in the case of stament lambdas. How ever, Expression lamdba has an advantage over statement lambda. When an expression lambda is assigned to a

variable of type Expression, the compiler emits code to build an expression tree that represents the

lambda expression, instead of a delegate instance.

1. //Example 4 - Expression Lambdas 2. 3. public delegate int BinaryOperationDelegate(int x, int y); 4. 5. class Program 6. { 7. static void Main(string[] args) 8. { 9. //Expression Lambda to delegate instance 10. BinaryOperationDelegate add =(a, b)=>a+b; 11. int result1 = add(20, 30); 12. 13. //Expression Lambda to Expression tree 14. Expression<BinaryOperationDelegate> addExpr = (a, b) => a + b; 15. 16. //Let us compile the expression tree before executing the same 17. var compiledAdd = addExpr.Compile(); 18. int result2=compiledAdd(20,30); 19. 20. 21. Console.WriteLine(result1); 22. Console.WriteLine(result2); 23. } 24. }

Page 6: Revisting C# V1.0

Revisiting C# 5

In the above example, you saw that we are assigning our expression lambda to the

System.Linq.Expression<TDelegate> to create an expression tree, and the compiling it to get the

actual delegate. Expression trees provide us a powerful way to represent code/logic as data, that can

be modified and/or interpreted at runtime if required.

Example Usages for Lambdas

These are some of the areas you may find using Lambdas pretty often.

To provide inline event handlers like

1. button.Click += (sender,args) => 2. { 3. };

To find items in a collection

1. var dogs= animals.Where(animal => animal.Type == "dog");

For iterating a collection, like

1. animals.ForEach(animal=>Console.WriteLine(animal.Name));

Creating a custom object

1. var myObj= mySource.Select(x => new {Name = x.name, Age= x.age});

Simple one line methods

1. Func<int, int> add = x => x + x;

For aggregate operations

1. double charCount = document.Sum(word => word.Length)

Page 7: Revisting C# V1.0

Revisiting C# 6

Creating Fluent Interfaces In C#

"FI(Fluent Interface) - when you use method chaining, after finishing the functionality, "return this",

and that's how you make it fluent".

This is a post about creating Fluent interfaces in C#, just to demonstrate various possibilities of Fluent

programming.

Chaining Methods - A Simple Scenario

Assuming that you are interested in training animals, let us start with a simple ITrainable interface. :)

1. 2. /// <summary> 3. /// Anything that is trainable 4. /// </summary> 5. public interface ITrainable 6. { 7. ITrainable Train(string skill); 8. ITrainable Do(string skill); 9. }

Well, nothing fancy there. Let us go ahead and create a Dog Class, which implements this interface. The only interesting piece you may find in the Dog class is, all methods are returning a type of ITrainable. As long as our Dog class implements ITrainable, we can return 'this', i.e the current Dog

Instance.

1. /// <summary> 2. /// Our simple dog class 3. /// </summary> 4. public class Dog : ITrainable 5. { 6. public string Name { get; set; } 7. public List<string> Skills { get; set; } 8. 9. public Dog(string name) 10. { 11. Console.WriteLine(); 12. Console.WriteLine("Dog " + name + 13. " created"); 14. 15. Name = name; 16. Skills = new List<string>(); 17. } 18. 19. //Let us train this skill to our dog 20. //Note that we are returning 'this', so that 21. //we can continue training or ask the dog to perform 22. public ITrainable Train(string skill) 23. { 24. Console.WriteLine("Dog " + Name + 25. " learned " + skill); 26. this.Skills.Add(skill);

Page 8: Revisting C# V1.0

Revisiting C# 7

27. return this; 28. } 29. 30. //Let us ask the dog to perform this skill 31. public ITrainable Do(string skill) 32. { 33. if (Skills.Contains(skill)) 34. Console.WriteLine("Dog " + Name + 35. " is doing " + skill); 36. else 37. Console.WriteLine("Dog " + Name + 38. ": Don't know how to " + skill); 39. 40. return this; 41. 42. } 43. }

Now, we are ready to train our Dog fluently. Like,

1. //Train one dog, Hope your name is not Bobby ;) 2. var dog = new Dog("Bobby"); 3. dog.Train("Running").Train("Eating") 4. .Do("Running").Do("Eating");

As you can see, we are chaining the method calls, because in each call, we are returning an object of type ITrainable. You'll see what Bobby is doing in the console

Dog Bobby created

Dog Bobby learned Running

Dog Bobby learned Eating

Dog Bobby is doing Running

Dog Bobby is doing Eating

Chaining Methods - For Collections

Now, let us do something more interesting. Let us create a couple of extension methods for all

collections of ITrainable. We do this by writing an extension method for IEnumerable<ITrainable>. If

you see, our extension methods are accepting a bunch of trainable organisms(?) (read,

IEnumerable<ITrainable>) and returns the same.

Leave out the Console.WriteLine(), it is there just for some pretty printing.

1. 2. 3. /// <summary> 4. /// Let us fluently train a bunch of Trainable 5. /// animals 6. /// </summary> 7. public static class TrainableExtensions

Page 9: Revisting C# V1.0

Revisiting C# 8

8. { 9. //Note that we are returning the IEnumerable<ITrainable> 10. public static IEnumerable<ITrainable> 11. Train(this IEnumerable<ITrainable> flock, string skill) 12. { 13. foreach (var member in flock) 14. member.Train(skill); 15. Console.WriteLine(); 16. return flock; 17. } 18. 19. //Ask all members to perform a skill 20. public static IEnumerable<ITrainable> 21. Do(this IEnumerable<ITrainable> flock, string skill) 22. { 23. foreach (var member in flock) 24. member.Do(skill); 25. Console.WriteLine(); 26. return flock; 27. } 28. 29. }

Now, let us create few dogs, and train them together :)

1. //Let us create the dogs and train them 2. var dogs = new List<ITrainable>{new Dog("Jimmy"), 3. new Dog("Sando"), 4. new Dog("Rob")}; 5. 6. //Now train them 7. dogs.Train("EatingFood").Train("Running") 8. .Do("EatingFood") 9. .Train("JumpingToRing").Do("Running");

And you'll see what they are doing, in this order.

Dog Jimmy created

Dog Sando created

Dog Rob created

Dog Jimmy learned EatingFood

Dog Sando learned EatingFood

Dog Rob learned EatingFood

Dog Jimmy learned Running

Dog Sando learned Running

Dog Rob learned Running

Page 10: Revisting C# V1.0

Revisiting C# 9

Dog Jimmy is doing EatingFood

Dog Sando is doing EatingFood

Dog Rob is doing EatingFood

Dog Jimmy learned JumpingToRing

Dog Sando learned JumpingToRing

Dog Rob learned JumpingToRing

Dog Jimmy is doing Running

Dog Sando is doing Running

Dog Rob is doing Running

Now, as LINQ methods are essentially extension methods on top of IEnumerable<T>, you can mix

and match the extension methods we just wrote, with LINQ methods. For example, if we decide only

Rob should learn a special skill (JumpingRing), you can do this.

1. dogs.Train("EatingFood").Skip(2) 2. .Train("JumpingRing").Union(dogs) 3. .Train("TakingPaper");

And you'll see how this works

Dog Jimmy learned EatingFood

Dog Sando learned EatingFood

Dog Rob learned EatingFood

Dog Rob learned JumpingRing

Dog Rob learned TakingPaper

Dog Jimmy learned TakingPaper

Dog Sando learned TakingPaper

And finally, Fluent APIs can be used for much more useful tasks (If you havn't yet realized, lol). Few

fluent API's I've come across

Rhino Mocks ReadableRex

Tweet#

Page 11: Revisting C# V1.0

Revisiting C# 10

Anonymous Types in C# and Object Initializer Syntax

This post is about the Anonymous types in C#, and the object initializer syntax. It is well known that starting from C# 3.0, you can initialize an object like this.

1. var boy = new { Name = "Jim", Age = 2 };

You specify the properties of an object, and at compile time, the compiler will create a new (anonymous) type, with the properties you specify, and with a constructor that can take the same

number of arguments. Now, let us examine our anonymous type in detail by using reflection. We'll examine whether the type is a class, along with the type's name. If you run this,

1. static void Main(string[] args) 2. { 3. 4. var boy = new { Name = "Jim", Age = 2 }; 5. 6. Console.WriteLine("Name=" + boy.GetType().Name); 7. Console.WriteLine("BaseType=" + boy.GetType().BaseType.Name); 8. Console.WriteLine("Asm=" + boy.GetType().Assembly.FullName); 9. Console.WriteLine("IsClass=" + boy.GetType().IsClass); 10. }

You'll get some output like

Name=<>f__AnonymousType0`2

BaseType=Object

Asm=AnonymousTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

IsClass=True

Needless to say, the Name will be a random name, and the Assembly's name depends on your own project name. The key point is, we just established that the type is there in the assembly - which means, as I mentioned, the compiler created a type at compile time itself. You can have a look at the IL if you are interested.

Now, let us examine the observation that the anonymous type has a constructor that takes the same

number of arguments as that of properties (i.e, in this case, the number of constructor arguments will be equal to the number of properties we specified in the object initializer, of types string and int). We can do that easily by creating a new instance of the anonymous type we have, using reflection. Add this to the tail end of the last piece of code.

1. //These two calls will fail with a run time exception, Just keep them commented 2. //var newboy = Activator.CreateInstance(boy.GetType(), null); 3. //var newboy = Activator.CreateInstance(boy.GetType(), new object[] { "Joe"}); 4. 5. //Only this will work. Creating a new boy 6. var newboy=Activator.CreateInstance(boy.GetType(),new object[]{"Joe",2});

Page 12: Revisting C# V1.0

Revisiting C# 11

7. 8. //Just write back the name of new boy 9. Console.WriteLine(newboy.GetType().GetProperty("Name").GetValue(newobj, null));

You can see that only the last call will work, as we need to pass the same number of arguments while instantiating. Note that you can have arrays of anonymous types as well, like this.

1. var guys = new[] 2. { 3. new {Name="Joe", Age=10}, 4. new {Name="James", Age=22}, 5. new {Name="Jim", Age=23}, 6. new {Name="Jerard", Age=10}, 7. };

Furthermore, I just want to mention one more point. You may not need to assign the property explicitly, when you use the object initializer syntax. Consider this code.

1. var guy1 = new { Name = "Ken", Age = 30 }; 2. var guy2 = new { guy1.Name, Age = 30 }; 3. 4. Console.WriteLine(guy1.GetType().Name + " - " + guy1.Name); 5. Console.WriteLine(guy2.GetType().Name + " - " + guy2.Name);

The key point to note here is, for guy 2, we are not explicitly specifying the Name property. Instead,

we are just specifying that the name of Guy2 is same as Guy1. The compiler will assume the property name from the given parameter's name (in fact, the last part of the specified parameter, in this case 'Name') - This is called Projection. Obviously, you'll find that both guy1 and guy2 are of the same type as well.

Can you guess the output of this code as well?

1. string Name = "Guy2"; 2. 3. var guy1 = new { Name = "Ken", Age = 30 }; 4. var guy2 = new { Name, Age = 30 }; 5. 6. Console.WriteLine(guy1.GetType().Name + " - " + guy1.Name); 7. Console.WriteLine(guy2.GetType().Name + " - " + guy2.Name);

Why anonymous types are interesting? Because we use them in various ways, especially while using LINQ syntax. Here is a basic example

1. var oldGuys = from guy in guys 2. where guy.Age > 20 3. select new { guy.Name };

Here, you'll probably find that we are using projection in the select new block. And as the last pointer,

just debug and observe the type of oldGuys, and have a look at the base's type.

Page 13: Revisting C# V1.0

Revisiting C# 12

Type Inference in Generic Methods

As you may already know, C# compiler doesn‟t support type inference for generic classes, but it

supports type inference for generic methods. To illustrate the point, let us consider a very simple

example.

1. class Program 2. { 3. //Our generic IsGreaterThan method 4. public static bool IsGreaterThan<T>(T x, T y) where T : IComparable<T> 5. { 6. return (x.CompareTo(y) > 0); 7. } 8. 9. static void Main(string[] args) 10. { 11. //You don't need to explicitly specify IsGreaterThan<int> 12. var result = IsGreaterThan(20,10); 13. Console.WriteLine(result); 14. } 15. 16. }

As you can see, we are not specifying the type explicitly, while calling our IsGreaterThan method - it is

inferred automatically by the compiler. That is simple, isn‟t it? Now, things become a a bit more

interesting when you combine Generic method type inference with extension methods. Have a look at

this code, we just made our IsGreaterThan<T> method an extension method.

1. public static class UtilExtensions 2. { 3. //Our generic IsGreaterThan extension method 4. public static bool IsGreaterThan<T>(this T x, T y) where T : IComparable<T> 5. { 6. return (x.CompareTo(y) > 0); 7. } 8. } 9. 10. class Program 11. { 12. static void Main(string[] args) 13. { 14. //You still don't need to explicitly specify IsGreaterThan<int> 15. var result = 20.IsGreaterThan(10); 16. Console.WriteLine(result); 17. 18. } 19. 20. }

As you can see, we are still good - the compiler can still infer the types. And of course, you can

leverage our IsGreaterThan against any IComparable implementation.

Page 14: Revisting C# V1.0

Revisiting C# 13

The Case Of switch-case in C#.

In Javascript, most developers prefer creating a lean object that can be re-used, instead of a stubborn

switch case. For example, instead of this Switch Case implementation,

1. switch (foo) { 2. case 'case1': 3. alert('case1 code'); 4. break; 5. case 'case2': 6. alert('case2 code'); 7. break; 8. default: 9. alert('hm, default code'); 10. break; 11. }

a number of developers may consider the below one as more elegant - because it is re-usable and

more testable.

1. var mySwitch= { 2. 'case1' : function() { 3. alert('case1 code'); 4. }, 5. 'case2' : function() { 6. alert('case2 code'); 7. }, 8. 'default' : function() { 9. alert('default code'); 10. } 11. }; 12. 13. 14. if (mySwitch[foo]) { 15. mySwitch[foo](); 16. } else { 17. mySwitch['default'](); 18. }

I was thinking about implementing something along similiar lines in C#, to re-factor few fat switch cases using a Dictionary. Obviously, this is context specific - one approach won't fit all the scenarios. Here is a quick example to clarify the point.

1. public class SwitchCase : Dictionary<string,Action> 2. { 3. public void Eval(string key) 4. { 5. if (this.ContainsKey(key)) 6. this[key](); 7. else 8. this["default"](); 9. } 10. } 11.

Page 15: Revisting C# V1.0

Revisiting C# 14

12. 13. //Now, somewhere else 14. 15. var mySwitch = new SwitchCase 16. { 17. { "case1", ()=>Console.WriteLine("Case1 is executed") }, 18. { "case2", ()=>Console.WriteLine("Case2 is executed") }, 19. { "case3", ()=>Console.WriteLine("Case3 is executed") }, 20. { "case4", ()=>Console.WriteLine("Case4 is executed") }, 21. { "default",()=>Console.WriteLine("Default is executed") }, 22. }; 23. 24. mySwitch.Eval(c);

This provides loose coupling, and you can even modify the logic for each case easily using a setter or

so.

Page 16: Revisting C# V1.0

Revisiting C# 15

C# 4.0 dynamic Features – Under the hood

In this post, we‟ll go back to the basics to uncover few interesting aspects of C# 4.0 dynamic features.

Let us start with a simple experiment.

Static Typing or Early Binding

Let us start with a bare minimum program. Fire up VS2010 and try the following code.

It is obvious that this won‟t compile. Simply because, the compile/design time checking ensures type

safety - and as we don‟t have a method named SomeStupidCall in our Human class, we can‟t compile

the same.

So, that is what you get.

Duck Typing or Dynamic Typing or Late Binding

Page 17: Revisting C# V1.0

Revisiting C# 16

Now, let us take a step back, and modify the above code like this. Change the type of variable h to „dynamic‟. And Compile. Here is a little surprise!! You got it compiled!! By using „dynamic‟ keyword, you just told the compiler, “dude, don’t bother if SomeStupidCall() is there in the Human type”

And now, run the application. The application will break for sure. But hey, that is your fault, not the

compiler‟s.

By the way, why we call dynamic typing as „Duck typing‟?

Page 18: Revisting C# V1.0

Revisiting C# 17

Here we go, Quoted from Wikipedia

In duck typing, one is concerned with just those aspects of an object that are used, rather than with

the type of the object itself. For example, in a non-duck-typed language, one can create a function

that takes an object of type Duck and calls that object's walk and quack methods. In a duck-typed

language, the equivalent function would take an object of any type and call that object's walk and

quack methods. If the object does not have the methods that are called then the function signals a

run-time error. It is this action of any object having the correct walk and quack methods being

accepted by the function that evokes the quotation and hence the name of this form of typing.

Now, why you need ‘dynamic’ at all?

I hope the above scenario is „good‟ enough to give you an „evil‟ impression about the dynamic

features. But, wait. There are lot of scenarios where the dynamic features can really simplify things for

you. For example, let us assume a reflection based scenario, where you load a type (from an external

assembly or so), to invoke a member. Here is a quick example. You‟ll see how to use dynamic as an

easier alternative for reflection. This is much more evident when you deal with scenarios like COM

interop etc. We‟ll see more interesting uses later.

Page 19: Revisting C# V1.0

Revisiting C# 18

How a ‘dynamic’ type is getting compiled?

Let us get back to a basic example. Consider a human class, with a Walk() method and Age property.

Now, let us create a new Human and assign this to a dynamic variable „h‟.

Page 20: Revisting C# V1.0

Revisiting C# 19

Let us build the above application. Fire up Reflector, open the binary executable of the app, and have

a look at the same. With a bit of cleanup, this is the relevant part of the disassembled code - which is

the equivalent 'statically‟ typed code generated by the compiler, for the „dynamic‟ code we wrote

above.

You‟ll see a „SiteContainer‟, for keeping track of the context, and two call site fields.

And here is the disassembled code for the member invocations. It might be interesting to note that,

the variable „h‟ is compiled as a simple CLR „object‟. Wow, from the CLR point of few, there is nothing

like a „dynamic‟ type. Instead, all member invocations to our „dynamic‟ object are modified; in such a

way that they are piped through a dynamic Call Site. The Call Site is initialized with the Binder

responsible for run time binding. In this case, you may note that the C# run time binder will be used

to invoke the members(Microsoft.CSharp.RuntimeBinder.Binder „s InvokeMember will return a CallSite

binder, that‟ll be used by the Call Site).

Page 21: Revisting C# V1.0

Revisiting C# 20

You might be thinking how the code will be generated for scenarios where, you have a method that

accepts or returns a „dynamic‟ type, or a property that gets or sets a dynamic type. Let us try this out.

Change our above Human class in the above example, to something like this. Note that now Walk

method accepts a dynamic type, and Age property is also modified to get/set dynamic types.

Page 22: Revisting C# V1.0

Revisiting C# 21

Have a sneak peak using Reflector. You‟ll note that, the compiler has generated a special [Dynamic]

attribute to the input parameter of Walk() method. Also, the getter and setter of the Age property is

also decorated with the [Dynamic] attribute, as shown below.

Conclusion

And here is some code of the final form of our experiment. Create a Console app in C# 4.0, to play

with this.

1. using System; 2. using System.Collections.Generic; 3. using System.Linq; 4. using System.Text; 5. using System.Runtime.CompilerServices; 6. using Microsoft.CSharp.RuntimeBinder; 7. 8. namespace DynamicTest 9. { 10. class Human 11. { 12. public void Walk(dynamic place) 13. { 14. Console.WriteLine("I'm walking to " + place); 15. } 16. public dynamic Age { get; set; } 17. } 18. 19. class Program 20. { 21. // Methods 22. private static void Main(string[] args) 23. {

Page 23: Revisting C# V1.0

Revisiting C# 22

24. //dynamic h = new Human(); 25. //h.Walk("Paris"); 26. //h.Age = 10; 27. 28. //will get compiled to 29. 30. object h = new Human(); 31. 32. //Create the site 1 if it is null 33. if (SiteContainer0.Site1 == null) 34. { 35. SiteContainer0.Site1 = CallSite<Action<CallSite, object, string>>.Create 36. (Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "Walk", 37. null, typeof(Program), new CSharpArgumentInfo[] 38. { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), 39. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.LiteralConstant 40. | CSharpArgumentInfoFlags.UseCompileTimeType, null) })); 41. } 42. SiteContainer0.Site1.Target(SiteContainer0.Site1, h, "Paris"); 43. 44. //Create the site 2 if it is null 45. if (SiteContainer0.Site2 == null) 46. { 47. SiteContainer0.Site2 = CallSite<Func<CallSite, object, int, object>>.Create

48. (Binder.SetMember(CSharpBinderFlags.None, "Age", typeof(Program), 49. new CSharpArgumentInfo[] 50. { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), 51. CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.LiteralConstant |

52. CSharpArgumentInfoFlags.UseCompileTimeType, null) })); 53. } 54. SiteContainer0.Site2.Target(SiteContainer0.Site2, h, 10); 55. } 56. 57. 58. // Nested Types 59. [CompilerGenerated] 60. private static class SiteContainer0 61. { 62. // Fields 63. public static CallSite<Action<CallSite, object, string>> Site1; 64. public static CallSite<Func<CallSite, object, int, object>> Site2; 65. } 66. 67. } 68. 69. }

Page 24: Revisting C# V1.0

Revisiting C# 23

Mr ExpandoObject in C# 4.0

.NET framework 4.0 has a cool new ExpandoObject class, in System.Dynamic namespace. What

makes this special is, it allows you to create an object with members that can be dynamically added

and removed at run time.

To clarify the point, have a look at this example.

1. dynamic obj = new ExpandoObject(); 2. obj.Value = 10; 3. var action = new Action<string >((line) => Console.WriteLine(line)); 4. obj.WriteNow = action; 5. obj.WriteNow(obj.Value.ToString());

And you'll get 10 as output in your console. As you can see, the property 'Value' and method 'WriteNow' is attached at runtime, when the invocation happens. The objective of this post is to examine how the ExpandoObject itself is implemented. To make this clear, let us create a MyExpando class, a minimal implementation of ExpandoObject.

We are inheriting MyExpando class from the DynamicObject, and these are the major methods we are overriding. TrySetMember- Provides the implementation of setting a member.

TryGetMember-Provides the implementation of getting a member.

TryInvokeMember- Provides the implementation of calling a member. GetDynamicMemberNames- Returns the enumeration of all dynamic member names. And Here is our minimal MyExpando class, inherited from DynamicObject, and overrides the above methods.

1. public class MyExpando : DynamicObject 2. { 3. 4. private Dictionary < string, object > _members = new Dictionary < string, object

> (); 5. 6. 7. /// <summary> 8. /// When a new property is set, add the property name and value to the dictionary

9. /// </summary> 10. public override bool TrySetMember(SetMemberBinder binder, object value) 11. { 12. if (!_members.ContainsKey(binder.Name)) 13. _members.Add(binder.Name, value); 14. else 15. _members[binder.Name] = value; 16. 17. return true; 18. } 19.

Page 25: Revisting C# V1.0

Revisiting C# 24

20. /// <summary> 21. /// When user accesses something, return the value if we have it 22. /// </summary> 23. public override bool TryGetMember(GetMemberBinder binder, out object result) 24. { 25. if (_members.ContainsKey(binder.Name)) 26. { 27. result = _members[binder.Name]; 28. return true; 29. } 30. else 31. { 32. return base.TryGetMember(binder, out result); 33. } 34. } 35. 36. /// <summary> 37. /// If a property value is a delegate, invoke it 38. /// </summary> 39. public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, ou

t object result) 40. { 41. if (_members.ContainsKey(binder.Name) && _members[binder.Name] is Delegate) 42. { 43. result = (_members[binder.Name] as Delegate).DynamicInvoke(args); 44. return true; 45. } 46. else 47. { 48. return base.TryInvokeMember(binder, args, out result); 49. } 50. } 51. 52. 53. /// <summary> 54. /// Return all dynamic member names 55. /// </summary> 56. /// <returns></returns> 57. public override IEnumerable&ltstring> GetDynamicMemberNames() 58. { 59. return _members.Keys; 60. } 61. }

Whenever a property set operation happens, the runtime will invoke TrySetMember, and there, we are pushing the property name and value to a dictionary. Similarly, whenever a get operation happens (TryGetMember), we are simply returning the value object if available in the dictionary. Also, when a

method call is made (TryInvokeMember), if the value type is a delegate, we just invoke the same by passing the arguments we received. Pretty simple, huh? Well, that is it. Now, let us try the above scenario with our MyExpando object

1. dynamic obj = new MyExpando(); 2. obj.Value = 10; 3. var action = new Action<string>((line) => Console.WriteLine(line)); 4. obj.WriteNow = action; 5. obj.WriteNow(obj.Value.ToString());

Run the application, and guess what you get!!

Page 26: Revisting C# V1.0

Revisiting C# 25

C# Enums – A Second Look

Consider the following code, where you accept a caller key and a token request from a caller, to issue

a security key for further requests? Note that we also have a minimal exclusion check, where we

prevent certain callers from getting the admin permission. Now, the question. What is wrong with the

code below?

1. public enum SecurityToken 2. { 3. Admin, 4. Registered, 5. Anon 6. } 7. 8. public class SecurityGateway 9. { 10. public string GetSecurityKey(string callerKey,SecurityToken token) 11. { 12. 13. //Prevent caller2 from getting the admin token 14. if (callerKey.Equals("secretcallerkey2") 15. && token == SecurityToken.Admin) 16. return "Error: You can't request an admin token"; 17. 18. //Issue the token 19. switch (token) 20. { 21. case SecurityToken.Anon: 22. return "PermissionKeyForAnonymous"; 23. case SecurityToken.Registered: 24. return "PermissionKeyForRegistered"; 25. default: 26. return "PermissionKeyForAdmin"; 27. } 28. } 29. }

If you already found the issue, you may stop reading here. Otherwise, let us examine this in a bit detail. Assume that a caller, let us sayCaller1, is requesting a security key for leveraging admin permissions.

1. SecurityGateway gateway = new SecurityGateway(); 2. 3. //Caller 1 4. var key = gateway.GetSecurityKey("secretcallerkey1", SecurityToken.Admin);

5. //key's value is PermissionKeyForAdmin for secretcallerkey1

As you may imagine, the value of key will be PermissionKeyForAdmin, as expected.

Page 27: Revisting C# V1.0

Revisiting C# 26

Now, the issue. As you may be aware, C# enums are implemented as integers by default, and you can cast integers to an enum type. So, if the Caller2 has some evil plans, it may do something like this.

1. SecurityGateway gateway = new SecurityGateway(); 2. 3. //Caller 2 4. var key = gateway.GetSecurityKey("secretcallerkey2", (SecurityToken)10); 5. 6. //OOps, key's value is still PermissionKeyForAdmin for secretcallerkey2, 7. //bypassing the exclusion check we've above 8.

Note that I'm casting an integer to an enum, and the following exclusion check will be bypassed by

Caller2, because the token's value is 10, instead of the value for SecurityToken.Admin.

1. //OOps, Caller2 can bypass this exclusion check 2. 3. //Prevent caller2 from getting the admin token 4. if (callerKey.Equals("secretcallerkey2") 5. && token == SecurityToken.Admin) 6. return "Error: You can't request an admin token";

Alright, so the point is, be a bit more careful when working with Enums in general, and also when you

implement check conditions with enums.

Now, there is a better solution - An explicit check using Enum.IsDefined(..) to validate if the passed

value exists in the specified enumeration is the best solution.

Page 28: Revisting C# V1.0

Revisiting C# 27

Top 5 Developer Mistakes C# Developers Should Not Commit

Some time back, I asked a question in Stackoverflow.com, about common programming mistakes

.NET developers must avoid. The response was awesome, to say the least. I‟m just listing down the

top 5 developer crimes I picked, from the answers I received (regardless the votes).

1. Breaking the stack unnecessarily when you re-throw an exception

This a pretty „old thing‟ - but surprisingly, still a very common mistake.

As TheSoftwareJedi mentioned, you don‟t really need to break the stack while throwing exceptions.

I‟ve done this myself when I was a beginner - and I‟ve seen this more often than anything else when I

do code reviews these days.

To clarify the point - What is the difference between

try { ..} catch (Exception ex) { throw ex; }

and

try {..} catch(Exception ex) { throw; } ?

And when you lose the stack trace, you can‟t debug your app – and even worse, you can‟t log your

error details properly to your error log.

The MSDN guidelines on exception handling clearly states

Page 29: Revisting C# V1.0

Revisiting C# 28

Do not rethrow by throwing the same exception object. This causes the stack trace for the original

exception to be lost--use a lone "throw;" statement (without an object following it) to "rethrow" a

catch exception.

2. Not using using to dispose objects

When ever you initialize an IDisposable object, it is a good practice to initiate it in a using statement

to ensure the object is getting disposed properly, like this.

Most developers won‟t do that. Greg Dean pointed the same.

Here is a little bit of re-cap from MSDN

As a rule, when you use an IDisposable object, you should declare and instantiate it in a using

statement. The using statement calls the Dispose method on the object in the correct way, and it

also causes the object itself to go out of scope as soon asDispose is called. Within the usingblock, the

object is read-only and cannot be modified or reassigned.

The using statement ensures that Dispose is called even if an exception occurs while you are calling

methods on the object. You can achieve the same result by putting the object inside a try block and

then calling Dispose in a finally block; in fact, this is how the using statement is translated by the

compiler.

Also, do you know that a using statement is expanded by the compiler to a try{..} finally{..} block at

compile time? Read more tips about using statement in MSDN.

3. Not unhooking event handlers appropriately after wiring them.

I think Scott Langham brought up a great point about not unhooking event handlers. People don‟t

really „remember‟ to unhook events.

Page 30: Revisting C# V1.0

Revisiting C# 29

In C#, when you register an event handler, you are creating a strong reference from the event source

to the listener. So, the listener won‟t get garbage collected even if you don‟t have any pointers to the

listener - unless you unhook the event by yourself, and this might even result in a memory leak.

So, if you are thinking about how to deal with situations where your Source is having a longer life

span than the listener – there are multiple ways to deal with it, and Daniel Grunwald covers them

nicely in this excellent Codeproject Post.

4. Forgetting that Strings are immutable

In .NET, we know that strings are immutable – which means, once a string is created, its value can‟t

be changed. All string operations you perform, actually returns a new string containing the

modification.

John Sonmez have a nice point with an example.

5. Not Overriding GetHashCode when overriding Equals method in C#

Why this is important? If Hashcode of two items does not match, they‟ll be never considered equal,

and the Equals method will never be called to execute your custom comparison logic – let us say, in

scenarios where your objects are used as a key in a dictionary or so. Hence, in first place, you should

Page 31: Revisting C# V1.0

Revisiting C# 30

override GetHashCode and return the same value for two equal objects based on comparison logic.

I‟ve seen this a couple of times during code review.

So, though Mark Gravell has several interesting points in his answer, my pick is about not overriding

GetHashCode when you override Equals method in C#.

Page 32: Revisting C# V1.0

Revisiting C# 31

4 .NET 4.0 Libraries You Should Know About

In this post, I‟ll consolidate few posts on four .NET libraries/frameworks, that‟ll help you write better

apps

MEF or Managed Extensibility Framework -

System.ComponentModel.Composition

MEF or Managed Extensibility Framework is cool. Firstly, it allows you to decouple your components

pretty easily. Secondly, it supports various component discovery scenarios, and enables you to write

better frameworks.

An Introduction to MEF- Creating a Zoo And Animals MEF or Managed Extensibility Framework and Lazy<T> – Being Lazy with MEF, Export Attributes

etc

Reactive Extensions and LINQ To Events – System.Reactive

Reactive Extensions will soon become the de-facto for writing asynchronous code in a declarative

manner .NET Rx gives greater freedom to compose new events – you can create specific events out of

general events

What is LINQ To Events

Concepts And First Look Linq To Events – A WPF Drawing Demo A Text Template for generating GetEventName wrapper

Parallel Extensions and Tasks – System.Threading.Tasks

With those multi core processors everywhere, support for parallelism is an already implicit

requirement for any new application. NET 4.0 framework provides a wealth of easy to use primitives

and abstractions to enable developers to quickly write parallel programs, targeting multi core

machines.

An Introduction to Tasks in Parallel Extensions

Dynamic Extensions – System.Dynamic

C# 4.0 introduced dynamic capabilities (duck typing) capabilities. There are a number of scenarios

where the dynamic features can really simplify things for you. For example, let us assume a Reflection

based scenario where you load a type (from an external assembly or so) to invoke a member, or think

about a dynamic fluent wrapper on top of XML or JSON.

An introduction to C# 4.0 dynamic keyword Understanding ExpandoObject in .NET 4.0 A Dynamic Wrapper in .NET 4.0

Page 33: Revisting C# V1.0

Revisiting C# 32

Further Reading

Also, check out my EBook on Design patterns here

Published Software Design Patterns For Everyone Ebook

On the C# side, here are few more interesting reads for you.

7 Freely Available Ebooks For .NET developers Top 7 Coding Standards & Guideline Documents For C#/.NET Developers 5 Back to Basics C# Articles - Fluent Interfaces, Expr Trees etc

3 Gems from Mono to spice up your .NET Apps Top 5 Common Mistakes .NET Developers Must Avoid 6 Cool VS2010 Tips you may find interesting 4 .NET 4.0 Libraries you *should* know about