Lambda Expressions

Contents

1. History

Lambda is the name of the Greek letter Lambda.
 
In the lambda calculus branch of computer science (from 1930 until now!), lambda expressions are use to represent functions. Functional programming (e.g. F#, Haskell, OCalm, …) evolved from lambda calculus, which is gaining momentum because it offers an elegant and easy way to solve certain issues. C# is an object oriented language from origin, but functional programming had a lot of influence in later versions of C#.
 
In lambda calculus, we would write a function square, which multiplies a number with itself, as follows:

square= \lambda n \Rightarrow  n*n

This can literally be read as follows: “square is a function that has an argument n, and has n*n as result
 

2. Introduction

Since version 3.0, C# offers support for these “Lambda’s”.
The support for lambdas doesn’t offer new functionality, it’s just “syntactic sugar” to write anonymous delegates compacter – and most of all more readable.
 
In the previous article in this collection, we’ve learned to use anonymous delegates. One thing you’ve probably noticed that the syntax isn’t that readable. We can make that code more readable by making use of the lambda operator (=>). The “Even and Odd” example of the previous article can be rewritten to the following code:
 

Console.WriteLine(“Even”);

List<int> result = Find(myList, number => number % 2 == 0);

foreach (int i in result)
    Console.WriteLine(i); 

Console.WriteLine(“Odd”);

result = Find(myList, number => number % 2 != 0);

foreach (int i in result)
    Console.WriteLine(i);

The expression number => number % 2 == 0 replaces the previous anonymous delegate code. This line states that a delegate with a parameter number should be executed (this is the signature of the delegate), and the lambda operator (=>) is followed by the implementation. Do take into account that the code above is the most compact form of lambda expressions (see paragraph “Different notations”). Lambda expressions are also used in LINQ, which we shall discuss in a future article. 
 
The syntax can appear odd in the beginning, but for those who are accustomed with functional programming languages as Haskell or F#, this shall appear very accustomed. After a bit of practice, the syntax will grow on you!
 

3. Different notations

There are many different ways to write lambda expressions, one more readable than the other. Below you can find a list of all possible notations. Take into account that the expressions below can have a return type, but that it’s not obligatory. 
 

(int x) => { return x * x; }

A simple expression which calculates the square of a number. A parameter of type int is expected, and explicitly mentioned.
 

x => { return x * x; }

The same expression as the previous statement, but the type of the parameter isn’t mentioned explicitly, meaning this code will also work with a double.
 

x => x * x

The shortest notation up until now. The return statement is facultative.
 

() => 3 * 3

An expression without parameters. This expression can have a return type, but it doesn’t have to; you can also call a function without return value.
 

(x,y) => { x++; return x * y; }

An expression with multiple parameters.
 

(int x, int y) => { x++; return x * y; }

An expression with multiple parameters, which explicitly are of type int.
 

4. Recap

  1. If an expression has parameters, then they are between parentheses left of the lambda operator. The types of the parameters are optional, unless the compiler isn’t smart enough to determine to type himself.
  2. Lambda expressions can have a return value, but this isn’t obligatory. If there is a return value, it must match the delegate to which it’s added.
  3. The body of an expression can be a simple expression or a block of C# code.
  4. Variables which are declared in an expression go out of scope when the method ends.
Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Anonymous delegates

Contents

1. Quick recap

1.1 delegates

  1. A delegate is an object that refers to an object and a method. Delegates can be compared with c++ functors.
  2. Events are special implementations of delegates.
  3. Events are used in .NET to inject certain behaviour and provide a form of loose coupling between classes. When one creates a Button class, one doesn’t want to implement the behavior when someone clicks the button; the button doesn’t have to know about all possible programs and classes that want to handle the click event.

1.2 How to create an event?

  1. Declare a delegate that describes the signature of the method to call.

    public 
    delegate void TickEventHandler(int hours, int minutes, int seconds);
     
  2. Create an instance of the event handler.

    public 
    event TickEventHandler Tick;

  3. Execute all methods that have subscribed to the event.

    if
    (Tick != null
    {
          var now = DateTime.Now;
          Tick(now.Hour, now.Minute, now.Second);
    } 

1.3 How to subscribe to an event?

    1. Add a method that has a matching signature to the event handler.
    2. Subscribe to the event.

clock.Tick += DisplayClockTime;

1.4 Conventions

In the .NET framework, all events have the EventHandler signature (namespace System); meaning return type void and two arguments, the first of type object, the second of EventArgs or a type that derives from EventArgs:

public delegate void EventHandler(object sender, EventArgs args); 

If an event needs extra arguments, you have to create a class which derives from EventArgs:

public class TickEventArgs : EventArgs
{
  public readonly int Hours;

  public readonly int Minutes;

  public readonly int Seconds; 

  public TickEventArgs(int hours, int minutes, int seconds)…
}

2. Anonymous delegates

2.1 Introduction

Events use delegates. But there are other usages for delegates, searching through a list for example. The behavior or parameters that define which objects should be found is unique. The find algorithm isn’t. That’s why a ‘general’ find method that takes in a delegate as parameter is provided. The delegate then determines if an object matches the search criteria. This way, he find algorithm can do its job regardless of the criteria.
 
Take the academic example below. We want to copy items from one list to a new list. The values could be even, or odd. The behavior that defines which items should be copied is defined by delegates.
 

delegate bool Filter(int x);

List<int> myList = new List<int>() { 1, 2, 3, 4, 5 }; 

private List<int> Find(List<int> numbers, Filter filter)
{
    List<int> result = new List<int>();

    foreach (int i in numbers)
        // invoke the delegate
        if (filter(i) == true)
            result.Add(i); 

    return result;
} 

private bool IsEvenNumber(int number)
{
    return (number % 2 == 0);
} 

privat ebool IsOddNumber(int number)
{
    return (number % 2 != 0);
} 

private void Tester()
{
    Console.WriteLine(“Even”);

    List<int> result = Find(myList, IsEvenNumber);

    foreach (int i in result)
        Console.WriteLine(i); 

    Console.WriteLine(“Odd”);

    result = Find(myList, IsOddNumber);

    foreach (int i in result)
        Console.WriteLine(i);
}

So in the example above, we wrote a method which filters items from a list of integers. The values that need to be filtered are defined by a delegate. In this case we have two methods that match the signature of the filter delegate, IsEvenNumber and IsOddNumber.In the method Tester we execute the Find method twice, once with IsEventNumer and once with IsOddNumber as argument.
 
The code above works perfectly and achieves the behavior we need. The only problem is that, from a programmers perspective, it’s a lot of typing. The delegate filter has to be declare, methods that match the signature of the delegate have to be written, there must be a shorter way. And there is! Anonymous delegates!
 

2.2 Implementation

We’re going to rewrite the code above and make use of anonymous delegates. But first, let us define what anonymous delegates are. Anonymous delegates make use of anonymous methods, which are methods without name. An anonymous method is a block of code which is defined inline. An example shall clarify things:
 

Filter myEvenDelegate = delegate(int number) { return (number % 2 == 0); };

Above, we declare an anonymous delegate of type Filter. We can pass this delegate as argument to the Find method.
 

result = Find(myList, myEvenDelegate);

If we would use the delegate above only once, we wouldn’t have to store it in a variable or field, but call it inline:
 

result = Find(myList, delegate(int number) { return (number % 2 == 0); });

Now, let us rewrite the entire sort code by using anonymous delegates. You’ll see the code gets a lot shorter!
 

delegate boolFilter(int x);

List<int> myList = new List<int>() { 1, 2, 3, 4, 5 }; 

private List<int> Find(List<int> numbers, Filter filter)
{
    List<int> result = newList<int>();

    foreach (int i in numbers)
    {
        // invoke the delegate
        if (filter(i) == true)
            result.Add(i);
    }

    return result;
} 

private void Tester()
{
    Console.WriteLine(“Even”);

    List<int> result = Find(myList, delegate(int number) { return (number % 2 == 0); });

    foreach (int i in result)
        Console.WriteLine(i); 

    Console.WriteLine(“Odd”);

    result = Find(myList, delegate(int number) { return (number % 2 != 0); });

    foreach (int i in result)
        Console.WriteLine(i);
}

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Events and delegates

Contents

1. Introduction

Events are of utter importance when making applications. One cannot assume that all actions of an application happen sequential. When an application runs, the user can press a button and some actions will happen accordingly. In .NET, this is done via events. When the user presses a button, all objects that have subscribed on that event are warned that an action should be performed. Events work via delegates, so let’s take a look at them first.
 

2. Delegates

2.1 General

A delegate is an object of type System.Delegate. It has two properties: ‘Method’ and ‘Target’. A delegate could be seen as a composition of a pointer to a method and an object. A delegate can be called just like a method. One could compare a delegate with a function pointer in C++ (although the internal implementation is very much like a functor), where you pass the object that handles the method. You can also use a delegate to refer to static methods; the ‘Target’ property then has null as value.
 

2.2 Usage

Let us create a delegate and use it. Make a new C# console application in Visual C# or Visual Studio. Add a class Clock.
Above the class declaration, we’ll declare a delegate, called TickDelegate. We do this by using the delegate keyword. Make sure this delegate has the public access specifier.

public delegate void TickDelegate(int hours, int minutes, int seconds); 

public class Clock
{ 

As you can see, declaring a delegate is simple and straight forward. It is written like an ordinary method without implementation, and by making use of the delegate keyword.
In the example above, the TickDelegate delegate can refer to a method without return type, and with 3 parameters of type integer. Take into account we’ve just declared the signature of the delegate, but haven’t made an instance that refers to a method and an object.
Add a public field to the class Clock, which is able to refer to a method which matches the signature of the TickDelegate. Call this field TickHandler.

    public class Clock
    {
        public TickDelegate TickHandler;
    }

Now add a method Tick to the class Clock that checks if the TickHandler delegate isn’t null and calls it subsequentially:

    public class Clock
    {
        public TickDelegate TickHandler; 

        public void Tick()
        {
            if (TickHandler != null)
            {
                var now = DateTime.Now;

                TickHandler(now.Hour, now.Minute, now.Second);

                Thread.Sleep(1000);
            }
        }
    } 

Now create a class ClockTester, and add a method DisplayTime that matches the signature of TickDelegate. Write the time to the console.

    class Clock Tester
    { 
        public void DisplayTime(int hours, int minutes, int seconds)
        {

            Console.WriteLine(“Hours {0}, Minutes {1}, Seconds {2}”,

                hours, minutes, seconds);
        }
    }

Create an object of type ClockTester and Clock in the Main method of the Program class. Assign the DisplayTime method of the ClockTester class to the TickHandler field. Call the method Tick of the ClockTester 10 times (via a for loop).

    static void Main(string[] args)
    {
        Clock clock = new Clock();

        ClockTester tester = new ClockTester();           

        // the Target property of the clock.TickHandler now refers

        // to tester, and the Method property refers to

        // the method DisplayTime of the ClockTester class.

        clock.TickHandler = new TickDelegate(tester.DisplayTime); 

        for (inti = 0; i < 10; i++)
        {
            // Here we indirectly call tester.DisplayTime

            // even though the Clock class doesn’t use ClockTester.

            clock.Tick();
        } 

        Console.ReadLine();
    } 

The assignment statement clock.TickHandler = new TickDelegate(tester.DisplayTime) doesn’t call tester.DisplayTime; it constructs a new instance of the TickDelegate class with Target=tester and Method=DisplayTime.  Since C# 2.0 the ‘new TickDelegate’ can be left from the statement, and you could just write:

            clock.TickHandler = tester.DisplayTime;

 

3. Delegates versus interfaces

Delegates offer a form a “loose coupling”, that is very important to build components that can communicate with other classes, without knowing of their existence. Take the following example into account: a button can call methods from a class that it doesn’t know exists. What if the creator of the button class had to know what class would ever use the button…
The delegates example from above could be written using interfaces, but this would lead to bigger, less readable code. Below you can find an example of the clock example with interfaces:

     interface ITickObserver
    {
        void HandleTick(inthours, intminutes, intseconds);
    } 

    class Clock
    {
        public ITickObserver Observer; 

        public void Tick()
        {
            if (Observer != null)
            {
                var now = DateTime.Now;

                Observer.HandleTick(now.Hour, now.Minute, now.Second);

                Thread.Sleep(1000);
            }
        }
    } 

    class ClockTester : ITickObserver
    {
        public void HandleTick(int hours, int minutes, int seconds)
        {
            Console.WriteLine(“Hours {0}, Minutes {1}, Seconds {2}”,

                hours, minutes, seconds);

        }
    } 

    class Program
    {
        static void Main(string[] args)
        {
            Clock clock = new Clock();

            ClockTester tester = new ClockTester(); 

            clock.Observer = tester; 

            for (inti = 0; i < 10; i++)
            {
                clock.Tick();
            } 

            Console.ReadLine();
        }
    }

Delegates aren’t just simpler to use – one doesn’t have to implement an interface – they also let you call methods indirectly from classed you can’t even inherit from (for example sealed classes).

 

4. Events and multicast-delegates

The clock class now supports only one handler (also referred to as observer or listener); in practice you almost always have multiple observers. You could simply solve this by using a List of type TickDelegate:

    public class Clock
    {
        private List<TickDelegate> m_TickHandlers; 

        public void AddTickHandler(TickDelegate tickHandler)
        {
            if( m_TickHandlers == null )
                m_TickHandlers = new List<TickDelegate>(); 

            m_TickHandlers.Add(tickHandler);
        } 

        public void RemoveTickHandler(TickDelegate tickHandler)
        {
            m_TickHandlers.Remove(tickHandler); 

            if (m_TickHandlers.Count == 0 )
                m_TickHandlers = null;
        } 

        public void Tick()
        {
            if (m_TickHandlers != null)
            {
                var now = DateTime.Now;

                foreach (TickDelegate tickHandler in m_TickHandlers)
                    tickHandler(now.Hour, now.Minute, now.Second);
            }
        }
    }

Because the code above occurs so much (this is the subject/observer pattern via delegates), there is a way to simplify this dramatically by using the so called “multicast-delegates”:

    public class Clock
    {
        private TickDelegate m_TickHandlers; 

        public void AddTickHandler(TickDelegate tickHandler)
        {
            m_TickHandlers += tickHandler;
        } 

        public void RemoveTickHandler(TickDelegate tickHandler)
        {
            m_TickHandlers -= tickHandler;
        } 

        public void Tick()
        {
            if (m_TickHandlers != null)
            {
                var now = DateTime.Now;

                m_TickHandlers(now.Hour, now.Minute, now.Second);
            }
        }
    }

Via the += and -= operators, we can respectively add and remove objects of type TickDelegate out of the internal list of TickDelegates. We also call this “subscribe to” and “unsubscribe from” a delegate. The compiler translate these operators into the following code:

        public void AddTickHandler(TickDelegate tickHandler)
        {
            m_TickHandlers = (TickDelegate) Delegate.Combine(m_TickHandlers,tickHandler);
        } 

        public void RemoveTickHandler(TickDelegate tickHandler)
        {
            m_TickHandlers = (TickDelegate) Delegate.Remove(m_TickHandlers, tickHandler);
        } 

To call all TickHandlers, we don’t have to iterate the list of TickDelegates ourselves, the call

          m_TickHandlers(now.Hour, now.Minute, now.Second); 

does this for us. This because .Net will internally use an instance of System.MulticastDelegate as soon as more than one TickHandler is added. Very handy! 
But because this case happens so much, they made a special syntax, via the event keyword: 
 

    public class Clock
    {

        private TickDelegate m_TickHandlers; 

        public event TickDelegate TickHandler
        {
            add { m_TickHandlers += value; }
            remove { m_TickHandlers -= value; }
        } 

Just like properties have get / set, an event has add / remove. 
To add a TickHandler, you can now write: 

          clock.TickHandlers += tester.DisplayTime; 

and to remove a handler: 

          clock.TickHandlers -= tester.DisplayTime; 

All the knowledge you’ve gained by reading the above yields to code below, which is much shorter and more readable than our initial case. 
 

    public class Clock
    {
        public event TickDelegate TickHandlers; 

        public void Tick()
        {
            if (TickHandlers != null)
            {
                var now = DateTime.Now;
                TickHandlers(now.Hour, now.Minute, now.Second);
            }
        }
    }

The compiler will generate the code needed for us, and we only have to type one rule of code (not taking the code to call event handlers into account).
 

5. Using Events

When writing a class, you should make sure it has methods, properties and events in order to make it easy to use. All Windows Forms controls use events, including the Form class.
As an example, let us rewrite the clock class, using the Windows Forms Timer. This example also shows it’s possible to use static methods as delegates; the value of the Target property is null in that case.

    public delegate void TickEventHandler(int hours, int minutes, int seconds); 

    public class Clock
    {
        public event TickEventHandler Tick; 
        private readonly Timer m_Timer = new Timer(); 

        public Clock()
        {
            m_Timer.Tick += Timer_Tick;
            m_Timer.Interval = 1000;
            m_Timer.Start();
        } 

        private void Timer_Tick(object sender, EventArgs e)
        {
            if (Tick != null)
            {
                var now = DateTime.Now;
                Tick(now.Hour, now.Minute, now.Second);
            }
        }
    } 

    public class Counter
    {
        private int m_TickCount; 

        public void OnTick(int hours, int minutes, int seconds)
        {
            m_TickCount += 1;

            Console.WriteLine(“{0}: {1}”, this, m_TickCount);
        }
    } 

    class Program
    {
        static void DisplayClockTime(int hours, int minutes, int seconds)
        {
            Console.WriteLine(“{0:D2}:{1:D2}:{2:D2}”, hours, minutes, seconds);
        } 

        static void Main(string[] args)
        {
            var clock = new Clock();

            var counter = new Counter();

            clock.Tick += DisplayClockTime;

            clock.Tick += counter.OnTick;

            Application.Run();
        }
    }

6. Conventions

In the .NET framework, all event have the EventHandler signature (namespace System):
 

public delegate void EventHandler(object sender, EventArgs args);

When an event has arguments, you need to make a new class that is derived from System.EventArgs:
 

public class TickEventArgs : EventArgs
{
  public readonly int Hours;

  public readonly int Minutes;

  public readonly int Seconds; 

  public TickEventArgs(int hours, int minutes, int seconds)…
}

The reason each eventhandler has matching signatures is that it can now be use to handle all kinds of events, even if the event uses a class that is derived from the EventArgs class.
 

7. Memory Leaks

Events do have some design issues you should be aware of. In .Net, the garbage collector decides when an object is to be removed. This happens when there are no more references to that object. Or more correctly, if an object can’t be reached by local, stack, global or static variables. Subscribing to an event is a strong reference. This means you also have to unsubscribe an object from the event when it’s no longer needed. If you don’t, you could create memory leaks. If an object isn’t referenced anymore, but the object is subscribed to an event, the object won’t be deleted. This because subscribing to an event adds a reference to the object via the Target property of the delegate.
 
 
Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Yield

Yield

Yield is a keyword that’s been added in C# 2.0. Yield simplifies making custom sequences and their iterators dramatically. Yield is used in conjunction with the return keyword, and returns a sequence of items (usually in a loop), with preservation of the state of the method over multiple calls. The compiler then generates the classes that implement IEnumerable (the sequence) and IEnumerator (the iterator) for you, where the MoveNext and Current methods of the iterator return the next item of the sequence. This sounds overly complicated, but it’s very easy to use and saves dozens of lines of code. Therefore an example, First without using yield:
 

foreach (var item in FindHeroes(new List<string>() { “x”, “y”, “z” }))
{
    Console.WriteLine(“Foreach: “ + item);
} 

static IEnumerable<string> FindHeroes(IEnumerable<string> herolist)
{
    var localheros = new List<string>(); 

    foreach (var hero in herolist)
    {
            localheros.Add(hero + “ADDED”);
    } 

    return localheros;

The purely academic example above contains a method FindHeroes, that has an IEnumerable of type string as parameter, and an IEnumerable of type string as return value. In this (again, purely academic) example, we copy the all heroes to a new list, and return this list. In a real world example one could combine or filter certain values. This is a pattern that occurs often: you have a list as parameter, you filter and / or combine certain values and return a new list. Unfortunately, the list has to fit in memory completely (e.g. a list of a billion heroes, each with their own avatar); to get over this issue one could write a custom sequence and iterator, but this ‘yields’ a lot of code where one gets overwhelmed. This can be done with a lot less and more readable code by making use of the yield keyword:
 

foreach (var item in FindHeroes(new List<string>() { “x”, “y”, “z” }))
{
    Console.WriteLine(“Foreach: “ + item);
}

static IEnumerable<string> FindHeroes(IEnumerable<string> herolist)
{
    foreach (var hero in herolist)
    {
        yield return hero + “ADDED”;
    }
}

The example above uses the yield keyword, and seems to be doing exactly the same as in the first example. This isn’t exactly true. In the first example the entire list is copied, and after that the foreach is executed that prints each item to the console.
 
In the second example, we don’t make a temporary list; the compiler converts the yield return to a sequence and iterator class for us. By using the yield keyword, a valye from the IEnumerable is returned, en then the program jumps back to the calling method – in this case the foreach that prints an item to the console. The next iteration of this foreach, the program jumps back to the current state of FindHeroes, and the next value is returned. Below you can find a summary:
 
Example 1: without yield
  1. A function is called
  2. The function is executed and a value is returned (in this example a list)
  3. The return value (list) is used further on in the program
     
Example 2: with yield 
  1. A function is called
  2. The caller asks for a new item
  3. An item is returned
  4. Jump back to step 2
Yields provides a more pull based implementation where items are returned one by one except of building an entire list and returning that.
Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Serialization

Contents

1. Definition

Serialization is the loading and saving of objects to a stream.
 
.NET offers support for this, which makes it very easy.
 

2. Binary Serialization

2.1 General

Take the following program: 

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary; 

[Serializable]
public class Hero
{
    public string Name { get; set; }
}

class Program
{
    static void Main()
    {
        var batman = new Hero { Name = “Batman” }; 

        string path = Path.GetTempFileName();

        // Save object to stream.
        using( var stream = File.Create(path) )
        {
                   var formatter = new BinaryFormatter();
                   formatter.Serialize(stream, batman);
        }

        // Load object from stream.
        using( var stream = File.OpenRead(path) )
       {
                   var formatter = new BinaryFormatter();
                   var batman2 = (Hero) formatter.Deserialize(stream);

           Console.WriteLine(batman2.Name);
       } 

        Console.ReadLine();
    }
}

The program above writes a Hero object to a file stream (Serialize), and then loads the object again (Deserialize).
 
The first thing you should notice is this:
 

[Serializable]
public class Hero
{
    public string Name { get; set; }
}

[Serializableis an “attribute”. This attribute tells the compiler that our Hero class can be serialized an deserialized. There are a lot of attributes, and you can make your own if you want. This shall be further discussed in the article about reflection.
 
Writing a an object to a stream via the binary serializer is very simple:
 

var formatter = new BinaryFormatter();
formatter.Serialize(stream, batman);

Deserializing an object isn’t rocket science either:

var formatter = new BinaryFormatter();
var batman2 = (Hero) formatter.Deserialize(stream); 

It is important to realize that we load a new instance of the Hero object; the instance we serialized remains unchanged.
 
The binary serializer only serializes fields; properties aren’t serialized. Auto-properties, like the hero’s Name, do work because they have a hidden field internally (the backing field), which is serialized.
 

2.2 Binary Serialization of objects with references

We extend the Hero class so it has a reference to another class (well, the same class :-) ).

[Serializable]
public class Hero
{
    public string Name { get; set; }

        public Hero BestFriend { get; set; }

class Program
{
    static void Main(string[] args)
    {
        var batman = new Hero { Name = “Batman” };

        var robin = new Hero { Name = “Robin” };

        batman.BestFriend = robin; 
        
robin.BestFriend = batman;

The rest of the code remains unchanged.
 
Note that when you serialize the batman object, the robin object is also serialized.
 
This is because .NET serializes an entire network of object (“Object Graph”). In this case, batman has a BestFriend backing field that refers to robin, which serializes robin.
 
Also of importance is that .NET deals with cyclic data structures correctly: batman refers to robin and vice versa.
 
Serialize

 

After deserialization, you have a new network of objects: a new batman and a new robin, which refer to each other. 
 

Serialize2

 

2.3 Binary Serialization: NonSerialized

Sometimes, you don’t want certain fields serialized, mostly because the values of these fields van be derived from other fields (often refered to as “cached fields’). Back-pointers (like in a parent / child tree structure) won’t be serialized as well because then you can’t serialize a portion of the structure.
 
You can obtain this behavior by using the [NonSerialized] attribute.
 

[Serializable]
public class Hero
{
    // No need to serialize name hash,
    // since we can compute that from the name field.
    [NonSerialized]
    private int m_NameHash; 

    private string m_Name; 

    public string Name
    {
        get { return m_Name; }       

        set
        {
            m_Name = value;
           UpdateNameHash();
        }
    } 

    public int NameHash
    {
        get { return m_NameHash; }
    } 

    private void UpdateNameHash()
    {
        m_NameHash = m_Name.GetHashCode();
    }
}

The field m_NameHash won’t be serialized. Of course we have a problem now: after deserializing, the value of the field will be 0 (the default value), and thus be incorrect. We can solve this via deserialization callbacks.
 

2.4 Binary Serialization: callbacks

In the previous example, we want to update the field m_NameHash after the object has been loaded. This behavior can be achieved by implementing the IDeserializationCallback interface.
 

[Serializable]
public class Hero : IDeserializationCallback
{
    // This method is invoked after the object graph is deserialized.
    void IDeserializationCallback.OnDeserialization(object sender)
    {
        UpdateNameHash();
    } 

     // No need to serialize name hash,
    // since we can compute that from the name field.
    [NonSerialized]
    private int m_NameHash;

In version 3.0 of the .NET framework, you can achieve the same behavior by placing attributes on a method. These attributes are [OnDeserializing], [OnDeserialized], [OnSerializing] and [OnSerialized].
 

2.5 Binary Serialization: advanced

Sometimes, you want to save an object in a completely different way. An example would be references to singletons; or references to objects that can’t be serialized, like Windows Forms controls. You can do this by using “Serialization surrogates”, or by implementing the ISerializable interface and using a special deserialization constructor. This way you can have full control.
 

3. XML Serialization 2.0

In version 2.0 of the .NET framework, you can serialize object to xml on a similar manner. The only drawback is that it’s very limited. You can only save public properties and cyclic structures (as batman and robin above) aren’t supported. You just add the [XmlAttribute] or [XmlElement] attribute to the fields you want to serialize.
 

4. XML Serialization 3.0

In version 3.0 of the .NET framework, Windows Communication Foundation (WCF) was added. WCF offers a number of advanced XML serializers, who are just as powerfull as the binary serializer, but make usage of xml. These serializers also work on fields.
 
First of all, you’ll have to add a reference to the System.Runtime.Serialization assembly.
 
Then, you can use the NetDataContractSerializer instead of the BinaryFormatter, and that’s that.
 

5. Nice XML Serialization 3.0

If you were to read the xml code generated by the NetDataContractSerializer, you would notice that it’s completely unreadable, which isn’t the intent of xml. It also refers to the exact datatypes used. Xml also has an important role when exchanging data, and it’s obvious the xml generated by the NetDataContractSerializer isn’t suited for this.
 
WCF offers another serializer – the DataContractSerializer – which can generate readable xml that hasn’t got the exact datatypes.
 
The DataContractSerializer can serialize fields as well as properties.
 
Unlike the serializers we’ve reviewed above, when using the DataContractSerializer, you must indicate which fields you do want to be serialized, not the other way around.
 
You use the attribute to [DataContract] indicate which classes you want to serialize, [DataMember] for fields or properties, and for [EnumMember] values of an enumeration. You can also set which name the xml element should have.
 
If you want to serialize cyclic data structures using the DataContractSerializer, you must call the constructor that has a preserveObjectReferences argument, and pass true.
Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)