Tuesday, 2 July 2013

Define page life cycle events with example in ASP .Net

Here You will get the solution of following queries:
Ques: What is page life cycle in asp .Net?
Ques: Describe events used in complete asp .net page life cycle.
Ques: Specify phase used in asp .Net page life cycle
Ques: Define Init, Load, Render and Unload events in page life cycle.


I L  R S U

I - Init
L-Load
R-Render
S-SaveState
U -Unload





Today I want to share some knowledge about ASP .Net. Every developer who is working on ASP .Net must know about the Page life cycle[first step of web development using .Net technology]. Some of our friends after having 2-3 years of ASP .Net experience still don't have proper knowledge about all the events used in Page Life Cycle . As a developer I always got confused about page life cycle events in my beginning days, Here I am describing all the events with examples wherever applicable.

PreInit 
PreInit is the first phase in asp.net page life cycle events. This is the place where one can dynamically set their master page in the code. In such case you can also set any theme or skin to your page, in PreInit we can also set the properties of the server controls of Master page, like the code below:

protected void Page_PreInit(object sender, EventArgs e)
{
if (textBox1 == null)
       {
          Response.Write("Pre Init, server control Not available");
       }
       else
       {
          string TextinInit = textBox1.Text;
          Response.Write("Pre Init, Server Control enabled");
       }

Page.MasterPageFile = "~/TestInitMaster.master";

       TextBox _mstTextBox = (TextBox)Page.Master.FindControl("txtMessage");
       Label _mstLabel = (Label)Page.Master.FindControl("lblMessage");

       _mstLabel.Text = "Setted in default page at time : " +ateTime.Now.ToString();
       _mstTextBox.Text = "Textbox set in default page";
  }

In above you can see I’ve used a master page dynamically and set a label and TextBox’s Text property of that master page in runtime that means we can set the master page dynamically and associate the values in their controls if any. If you try to set the masterpage in any other event after Page_PreInit event, you will get an error message that will tell you that the master page only can be set on or before Page_PreInit event. In Page_PreInit event you can also see at the top level I’m checking a TextBox1 value whether it’s null or not. It is a server control (TextBox), but in PreInit the value will always be null of this text box or any other server control. So if I want to conclude the thing, in Page_PreInit controls are not fully initialized. So use this event for setting MasterPage file in your code. Each control Unique ID’s are also available at this event.

Init  
Init is called when you can initialize your page controls, this is the place that comes into picture after each Control initialization, till this event they get their Unique Id, master page etc. In Init you cannot access any controls properties after the last viewstate, I mean suppose you enter some text in a textbox control and click on a button control that makes a postback, now you want to view the value latest entered. In such case you will be able to see the textbox value which you’ve entered after the round trip happens, this is because of ViewState property of controls. That means they preserved your last saved value, but you see this value after Init phase because, usually we don’t use these events in our code and use just Page_Load event where the Viewstate value already got loaded. But as in Init phase, we cannot access our latest entered values in textbox, so in Init you won’t be able to get the latest changes. So I can say in Init we won’t be able to get the postback value.

InitComplete
In this event, Viewstate functionality is turned on for server control. Viewstate of controls allows preserving their values across postback.

PreLoad
This is the first event where viewstate functionality starts retrieving their values. PreLoad executes after InitComplete method. In this method, page has loaded values from viewstate. So for example in a button click event if you create a viewstate like below than what will going to be happen:

protected void btnSubmit_Click(object sender, EventArgs e)
        {
            ViewState["myData"] = "just a text string";
        }

After button click, postback will happen at it will start calling page events like PreInit, Init, Initcomplete. Till these three events you will not be able to get the value of Viewstate “myData”. Even when the event fires PreLoad event of page, at this time you cannot access the ViewState, this is because ViewState will set the value when asp.net reaches the ButtonClick event, and this will happen after Load event, so one more time we will click on our submit button, and because now the ViewState[“myData”] resides into my page, I can access it on my PreLoad event. For better understanding please see the screen shot below:
ASP .Net page life cycle

Load
Most of the developers are familiar with the page load, as this is the only event that comes by default in aspx.cs page when you start doing anything with your code behind. The page Load events executes after the Page_PreLoad event. If you have created your own Load method in constructor of your code behing, then this will be the method that will execute before the Page_Load event and after Page_PreLoad event, for better understanding refer to the image below:
Init event in Page Life Cycle


As you are seeing in above code, I’ve created my own Page_Load event in my code behind as well as the default Load event, I didn’t mention Page_PreLoad event here, but it will execute after Page_InitComplete event. So back to the image, the _Default_Load will execute first before the Page_Load event. If you have any master page in your page, then the Load event of your master page will run followed by the user control Load event if they exist in your file.

Events
After the Page_load the next event is Page Control’s event. For example, if you have a control that raises postback just like button, and you clicked on the Button, so after Page_Load your Button_Click event will fire, and do the rest of the thing you’ve mentioned in your page. for better understanding please refer to the image below, event execution will be happen in that sequence how image is showing, in event portion whatever you will do that will go ahead and will do the things you’ve mentioned in you page. just like below, I said to create a ViewState[“myData”] and put some string inside that viewstate. So now the viewstate is ready to preserve ahead in my code. 

In Events you can also check the Page.IsValid property if you’ve used any validator controls in your page like regularexpressionValidator, requiredFieldValidator, Range etc. To check this property refer to the image below.
Load complete event of Page Life Cycle


LoadComplete
This event can be used when all the event processing has been done in the page.

PreRender/PreRenderComplete 

PreRender event gets called when page has created all the controls that user will see in his browser. PreRenderComplete is the last place to change anything in the page. After this event any changes will not get preserved in page cycle. 

SaveStateComplete
event gets fired immediately after the PreRenderComplete event, in this event the viewstate functionality and control state get saved, as I said in PreRenderComplete changes can be done that will affect the next postback. In SaveStateComplete you can do the changes in your server control, but the state won’t be available in next postbacks. 

Render 
Render is not an event but this is the phase where the HTML of your page will get rendered to the output stream with the help of HTMLTextWriter. You can override the Render method of page if you want to write your own code rather than the actual HTML text. As like below:

Render event of Page Life Cycle

As you can see in the code above, I’ve override the Render method in my code and write something with Heading 1 tag and later on called the base.render method. In current scenario the thing will happen is: apart my server controls code in my browser I’ll be able to see my Hello world text also. If I remove the base.render method calls, than I won’t be able to view my any control if I’ve created in page.


Unload 
This is the last event that gets fired. This is the page cleaning process like closing the open file connections etc, so in this process you cannot do any kind of manipulation with data that affect the rendering, you are restricted to use Response property also, and doing such you will get an exception message.

There might be some mistakes with this article but I tried my best to share with you, So if you have some queries OR suggestions please feel free and share the by comment. Thank you for reading this post..



Page_PreInit

Page_Init

Page_InitComplete

Page_PreLoad

Page_Load

Page_LoadComplete

Page_Prerender

Page_PrerenderComplete

Page_SavestateComplete

Page_Unload








--------------------


That's why I was pretty amused the other day when I happened to run across SILVER-U, which is a mnemonic device for remembering the ASP.NET page lifecycle. Here are the steps, along with the methods you'd most commonly want to handle or override at each step:
  • S - Start. (OnPreInit)
  • I - Initialize. (OnInit, InitComplete, OnPreLoad)
  • L - Load. (OnLoad)
  • V - Validation. (Validate)
  • E - Event Handling. (OnLoadComplete, OnPreRender, OnSaveStateComplete)
  • R - Render. (Render)
  • U - Unload. (OnUnload)
I thought this was kinda cool, so I'm passing it on.
Of course, this won't be replacing my all-time favorite, which applies equally well to ASP.NET as it does to life: PPPPPPP.


It can be difficult to remember exactly what happens and when during the ASP.NET page lifecycle. That in mind, often the easiest way to make sense out of a series of steps is to create an acronym. Microsoft shows us the basic steps of the ASP.NET page lifecycle below.
  1. Page Request
  2. Start
  3. Page Initialization
  4. Load
  5. Validation
  6. Postback event handling
  7. Rendering
  8. Unload
Putting together an acronym for these is easy enough. Since the Page Request technically isn't a part of the life cycle (it only indicates whether we actually will start the cycle or load a cached page) we won't include it in the acronym.
  • S – Start
  • I – Initialize
  • L – Load
  • V – Validate
  • E – Event Handling
  • R – Render
That gives us "SILVER", which is very easy to remember. However, it is important remember that the last part of the cycle is unload. You can remember it as "SILVER-U" or "SILVER-YOU" if that helps (but it just didn't quite fit into our acronym!). Now that it's easy to remember the order of steps for the page lifecycle, we'll summarize exactly what happens and what events are pertinent to each stage.

codeproject 
UsualDosage
Web Developer

First, you need to understand what is the Life Cycle of an ASP.NET page?
When you open a web page in the browser, it sends a request to the server and server processes this request and returns a page to the browser. This complete process is known as Life cycle of a page.
How it starts: The life of an ASP.NET page starts when the page is first requested by the user.
How it ends: It ends when the page is rendered completely to the browser.
Until now, it's simple. On the server side, the processing of an ASP.NET page is done in stages. At each stage, some events are fired. With these events, you can write your own code to handle any processing logic in ASP.NET page.
Now I will explain the different stages of ASP.NET page life cycle. I have seen many explanations of the Page Life cycle and none of them could make it into my favorite list. All the articles were very lengthy and complex. I will try to explain it in the simplest language with a clarity of thought.
Here are the list of stages:
I am writing this tip to explain the life cycle of the page. So I try to simulate and experience the complete life cycle of an ASP.NET page on my laptop. What I will do? I will start my browser and open an ASP.NET page. Then will tell you the complete story of the ASP.NET page life cycle right from when I start typing the page URL in the browser to final rendering of the page in my browser.
Let's start!
  1. Browser makes a request:I open my browser Mozilla and type the URL of an ASP.NET website. Let's say I typed http://woodland.com/. What does it means? This means that I made a request to the browser to open this page for me. Browser will send my request to the server on which this page is hosted.
  2. Page framework initialization: Page.Init event firesASP.NET checks whether the request is a new one or an old one. If the request is a new one, then ASP.NET creates the page. It generates the page with all the controls defined in the .aspx page.
    If the page request is an old one, then ASP.NET gets the data from View state and sets all the controls status View State information and page is returned to the browser.
  3. User Code Initialization: Page.Load event fires.In this event, initialization is done. Populating the dynamic controls or dropdown list is done in this event. This event always fires whether the page requested for the first time or page is requested as part of a postback. Initialization is to be done only on the first request. On a postback, you have to do nothing, ASP.NET restores the control properties automatically from View State information.
  4. Validation: After the page is loaded, validation controls gets fired and displays error messages. You just have to check whether the Page.IsValid is true or false.
  5. Event handling: Now the page is fully loaded and validated. This stage includes any events that fired after the last postback. There are 2 types of events in an ASP.NET page life cycle:

    1. Immediate Response events: For eg. Button click, link click, etc. These events trigger a postback immediately.
    2. Change Events: For example: Changing the selection in a dropdown list or in a Textbox. These events fire when the page is posted back next time.
  6. Browser receives response: Response and request properties of the page are unloaded and any cleanup operation if required is performed.Example: I believe that there is nothing better than an example to explain things. So I am providing you a page with a sample scenario.
I have created a page with a Textbox and a submit button. I have written some text in Textbox and click submit button triggering a Postback. Here is the list of events that fires in this example:

  1. Page.Init
  2. Page.Load
  3. Textbox.TextChanged
  4. Button.Click
  5. Page.PreRender
  6. Page.Unload
I hope the above explanation has given you a clear idea of how ASP.NET page executes and runs. You can use these events to write optimal and perfect code for your projects.




Recent Articles


















Tuesday, 25 June 2013

Delegates, Anonymous Methods and Lambda Expressions

Introduction


Like generics, delegates are one of those features that developers use without really understanding. Initially this wasn’t really a problem since delegates were reserved for fairly specific purposes: implementing callbacks and as the building-block for events (amongst a few other edge cases). However, each version of .NET has seen delegates evolve, first with the introduction of anonymous methods in 2.0 and now with lambda expressions in C# 3.0. With each evolution, delegates have become less of an specific pattern and more of a general purpose tool. In fact, most libraries written specifically for .NET 3.5 are likely to make heavy use of lambda expressions. As always, our concern isn’t just about understanding the code that we use, but also about enriching our own toolset. Seven years ago it wouldn’t have been abnormal to see even a complex system make little (or no) us of delegates (except for using the events of built-in controls). Today, however, even the simplest systems heavily relies on them.

Delegates


The best way to learn about all three framework/language feature is to start from the original and build our way up, seeing what each evolution adds. Delegates have always been pretty simple to understand, but without any good reason to use them, people never really latched on to the concept. It’s always easier to understand something when you can see what problem it solves and how it’s used – and examples of delegates always seem contrived.

Delegates are .NETs version of function pointers – with added type safety. If you aren’t familiar with C or C++ (or another lower level languages) that might not be very helpful. Essentially they let you pass a method into another method as an argument. Although many developers understand the concept in languages such as JavaScript, the strictness of C#/VB.NET makes it a little more confusion. For example, the following JavaScript code is completely valid (and even common):
function executor(functionToExecute)

{

   functionToExecute(9000);

}

var doSomething = function(count){alert(“It’s Over ” + count);}

executor(doSomething);

Although simplistic, the above code shows how a function can be assigned to a variable (not the return value mind you, the actual function body) and then passed around as a parameter into a function. This parameter can then be executed as you would any other function.

The only difference in .NET is that you can’t just assign any function to any variable and pass it into any method. Instead everything has to be properly typed. That’s where delegates come in, they let you define the signature for a method – its parameters and return type. So, to build the above code in C#, we use the following:
public delegate void NotifyDelegate(int count);

public class Executor

{

   public static void Execute(NotifyDelegate notifier)

   {

       notifier(9000);

   }

}
public class Program { public static void Main(string[] args) { NotifyDelegate notifier = Alert; Executor.Execute(notifier); } public static void Alert(int count) { Console.WriteLine(“It’s over {0}”, count); } }

It seems like a lot more code, but a good chunk of it is simply the requirement for everything in .NET to be in a class. The first, and most important, line is the definition for the delegate itself. Delegates are much like classes, interfaces, structures or enums – they define a type. Here we’ve defined a type named NotifyDelegate. Any method can be assigned to a variable of type NotifyDelegate provided that method has the same signature: it must return void and take a single parameter of type int. In the above code I explicitly assigned the Alert method to a variable named notifier for demonstration purposes only, the following would have been just as acceptable:
Executor.Execute(Alert);

The point is that a delegate can be used like any other type, the difference is simply that its assigned to a method. The other point to keep in mind is that my example used a static method (Alert). You can use either a static or an instance method – again, the only requirement is that it meets the defined method signature. Within an instance method you have access to all instance members just like any normal method (because it is a normal method).

Let’s Get More Practical


So we have an idea of what delegates are, but when would we use them? As I mentioned earlier, in their normal form, their usage is fairly reserved for specific cases, most notably callbacks (if you’ve ever used an asynchronous method you likely had to supply a delegate to be called when the async call completed). However, lets look at a real example in which you might use a delegate. Initially this is going to be a little contrived, but as we move the example to anonymous methods and then lambda expressions, the example will feel more natural. This is a real example I use in my code.

Within our data layer we have a method that expects an array of objects and saves them all within a transaction. The method looks something like this (we use NHibernate, but the implementation details don’t matter):
public class GenericStore<T>

{

    public void Save(params T[] entities)

    {

       using (var transaction = BeginTransaction())

       {

          try

          {

             foreach(T entity in entities)

             {

                Save(entity);

             }

             transaction.Commit();

          }

          catch(Exception)

          {

             transaction.Rollback();

          }

       }

    }

}

We use this method, for example, when we want to switch the default group, something like:
public void SwitchDefault(Group newDefault)

{

   var oldDefault = GetDefaultGroup(); //implementation isn’t important

   oldDefault.Default = false;

   newDefault.Default = true;

   DataFactory.For<Group>().Save(oldDefault, newDefault);

}

Of course, if our Save method throws an exception, we need to undo our code (rolling back the transaction undoes the database commit, but not the actual in-memory change we made). Here’s one way to do that:
public void SwitchDefault(Group newDefault)

{

   var oldDefault = GetDefaultGroup(); //implementation isn’t important

   oldDefault.Default = false;

   newDefault.Default = true;

   try

   {

      DataFactory.For<Group>().Save(oldDefault, newDefault);

   }

   catch

   {

      oldDefault.Default = true;

      newDefault.Default = false;

   }

}

This works fine, except we end up with a lot of try/catches all over the place. Instead we use a delegate (again, this is actually more code, but it’s just a foundation to progress to anonymous methods). Here’s our improved Save method:
public class GenericStore<T>

{

   public delegate void RollbackDelegate(T entities);
public void Save(params T[] entities) { Save(null, entities); } public void Save(RollbackDelegate rollback, params T[] entities) { using (var transaction = BeginTransaction()) { try { foreach(T entity in entities) { Save(entity); } transaction.Commit(); } catch(Exception) { transaction.Rollback(); if (rollback != null) { rollback(entities); } } } } }

The overloaded Save method is provided so that calling code can provide a delegate or not. We can use this code simply by doing:
public void SwitchDefault(Group newDefault)

{

   var oldDefault = GetDefaultGroup(); //implementation isn’t important

   oldDefault.Default = false;

   newDefault.Default = true;

   DataFactory.For<Group>().Save(SwitchDefaultRollback, oldDefault, newDefault);

}
public void SwitchDefaultRollback(Group[] groups) { groups[0].Default = false; groups[1].Default = true; }

Whether or not you consider this an improvement over the try/catch solution is largely a matter of taste. I find neither particularly elegant. The problem with the delegate solution is the need for the extra method, and the awkward use of array indexes (we’re relying on the Save method to pass the items back in the same order they were passed in).

Anonymous Methods


.NET 2.0 added a fairly significant improvement to delegates: anonymous methods. Delegates still exist and are still the ideal solution for a number of cases. However, for situations such as the one we’re developing, they are far from perfect. What we want is a more concise way to create our callback as well as something that’ll help us avoid the weird array indexing. Anonymous methods solve both those problem. We’ll address each point separately.

Probably the most intimidating aspect of anonymous method is the way they are declared. Unlike normal methods, anonymous methods are declared within another method, using the delegate keyword:
public void SwitchDefault(Group newDefault)

{

   GenericStore<Group>.RollbackDelegate rollback = delegate(Group[] entities)

   {

      groups[0].Default = false;

      groups[1].Default = true;

   };

   var oldDefault = GetDefaultGroup(); //implementation isn’t important

   oldDefault.Default = false;

   newDefault.Default = true;

   DataFactory.For<Group>().Save(rollback, oldDefault, newDefault);

}

Like any nested-type, we access our delegate via its full name (GenericStore<Group>.RollbackDelegate). The delegatekeyword creates an anonymous method – which behaves like any other method, except it isn’t named and exists within a limited scope. Again, I assigned the anonymous method to a variable for demonstrative purposes, in real life you’re more likely do to:
public void SwitchDefault(Group newDefault)

{

   var oldDefault = GetDefaultGroup(); //implementation isn’t important

   oldDefault.Default = false;

   newDefault.Default = true;

   DataFactory.For<Group>().Save(delegate(Group[] entities)

     {

        groups[0].Default = false;

        groups[1].Default = true;

     }, oldDefault, newDefault);

}

The syntax is more confusing. If you look at it, you’ll notice that we’re really just passing 3 parameters to our Savemethod – our anonymous method, oldDefault and newDefault. The syntax will improve considerably when we look at the next evolution. For now, it’s important that you understand the concept behind creating an anonymous method.

While the syntax might be the most confusing, the most important aspect of anonymous methods is their scope. Anonymous methods behave like any other code-block. In our above code that means that our anonymous method has access to oldDefaultnewDefault and all the other instance members which might be defined (like the GetDefaultGroupmethod we’re calling). That means that we can really simplify our code. First, we’ll change our delegate so that it no longer passes back our array of entities:
public delegate void RollbackDelegate();

Along with the corresponding part of our Save method:
transaction.Rollback();

if (rollback != null)

{

   rollback();

}

Our calling code now looks like:
public void SwitchDefault(Group newDefault)

{

   var oldDefault = GetDefaultGroup(); //implementation isn’t important

   oldDefault.Default = false;

   newDefault.Default = true;

   DataFactory.For<Group>().Save(delegate()

     {

        newDefault.Default = false;

        oldDefault.Default = true;

     }, oldDefault, newDefault);

}

I consider this much cleaner, not only because there’s less chance of bugs, but also because the code is far more readable. All ambiguity around what groups[0] and groups[1] referred to has been removed.

Our solution still isn’t perfect (the syntax around anonymous delegates is a little messy), but to me it’s definitely a step in the right direction. We no longer have to create a full-blown method for each delegate, and having our scoped within the method gives us direct access to variables we’ll likley need.

Lambda Expressions


While anonymous methods provide a new feature, lambda expressions merely provide an improved syntax. The improvement is rather significant though, which has made anonymous methods even more popular. At one point our delegate was passing along an array as a parameter:
public delegate void RollbackDelegate(T entities);

And, to be valid, our anonymous method had to be defined with the same signature:
delegate(Group[] entities){ … }

Although we’ve moved beyond the need to pass-back the array, I want to look at lambdas from this point on, as it’ll help make things clearer (and often times you’ll have delegates with parameters). The lambda version of our above code is:
entities => {….}

Essentially, the => operator (some people call it the wang operator) replaces the need for both the delegate keyword as well as the parameter types. Additionally, if your delegate is a single statement, you can drop the brackets { }. If you have multiple parameters, you wrap them in parenthesis:
(entities, transaction) => {…}

If you don’t have any parameters, like in our example, you use empty paranthesis:
() => {…}

It’s easy to get mixed up with the syntax, but if you walk backwards through the code, hopefully everything makes sense. Here’s what our implementation now looks like:
public void SwitchDefault(Group newDefault)

{

   var oldDefault = GetDefaultGroup(); //implementation isn’t important

   oldDefault.Default = false;

   newDefault.Default = true;

   DataFactory.For<Group>().Save(() =>{newDefault.Default = false; oldDefault.Default = true;}, oldDefault, newDefault);

}

Some More Examples


To get a good feel for the syntax, let’s look at some other, common, examples. We’ll stick to the List<T> class, which exposes a number of methods which expect delegates.

To get the sum of all integers within a list using an anonymous method:
var ids = new List<int>{1,2,3,4,5};

var sum = 0;

ids.ForEach(delegate(int i){ sum += i;});

Using a lambda expression:
var ids = new List<int>{1,2,3,4,5};

var sum = 0;

ids.ForEach(i => sum += i);

To find a specific group by its id:
public Group FindGroup(int id)

{

   var groups = GetAllGroups(); //there might be a more efficient way!

   return groups.Find(delegate(Group g){return g.Id == id;});

}

Using a lambda expression:
public Group FindGroup(int id)

{

   var groups = GetAllGroups(); //there might be a more efficient way!

   return = groups.Find(g => g.Id == id);

}

Notice that using a lambda we don’t even have to return true or false if a match is found. Lambdas explicitly returns the value.

Delegates and Generics


The last thing we’ll cover is the synergy between delegates and generics. This is something I’ve covered in depth before, so we’ll only briefly discuss it here. The .NET framework comes with a number of built-in delegates (for example, we might not need to define our own RollbackDelegate type as the .NET framework might already have one for the same method signature). It turns out that if you sprinkle some generic goodness of top of delegates, you can easily create a delegate for almost any situation. There are three core generic delegates within the .NET framework:PredicateFunc and Action. Each comes with a number of overloads to cover the most common cases:
delegate bool Predicate();

delegate bool Predicate<T1>(T1 parameter1);

delegate bool Predicate<T1, T2>(T1 parameter1, T2 paremter2);

delegate bool Predicate<T1, T2, T3>(T2 parameter1, T2 paremter2, T3 parameter3);
delegate T Func<T>(T returnType); delegate T Func<T, T1>(T returnType, T1 parameter1); delegate T Func<T, T1, T2>(T returnType, T1 parameter1, T2 paremter2); delegate T Func<T T1, T2, T3>(T returnType, T1 parameter1, T2 paremter2, T3 parameter3);
delegate void Action(); delegate void Action<T1>(T1 parameter1); delegate void Action<T1, T2>(T1 parameter1, T2 paremter2); delegate void Action<T1, T2, T3>(T1 parameter1, T2 paremter2, T3 parameter3);

The difference between the three is the type of the return (Predicate always returns boolFunc returns T and Actionreturns void). The overloads just let us support multiple parameters.

Instead of using this delegate:
public delegate void RollbackDelegate(T entities);

…

public void Save(RollbackDelegate rollback, params T[] entities){…}

We could have simply used:
public void Save(Action<T[]> rollback, params T[] entities){…}

And instead of:
public delegate void RollbackDelegate();

…

public void Save(RollbackDelegate rollback, params T[] entities){…}

We could have simply used:
public void Save(Action rollback, params T[] entities){…}


Anonymous Methods (C# Programming Guide)

Visual Studio 2005
97 out of 130 rated this helpful Rate this topic
In versions of C# previous to 2.0, the only way to declare a delegate was to use named methods. C# 2.0 introduces anonymous methods.
Creating anonymous methods is essentially a way to pass a code block as a delegate parameter. For example:
// Create a handler for a click event
button1.Click += delegate(System.Object o, System.EventArgs e)
                   { System.Windows.Forms.MessageBox.Show("Click!"); };

or
// Create a delegate instance
delegate void Del(int x);

// Instantiate the delegate using an anonymous method
Del d = delegate(int k) { /* ... */ };

By using anonymous methods, you reduce the coding overhead in instantiating delegates by eliminating the need to create a separate method.
For example, specifying a code block in the place of a delegate can be useful in a situation when having to create a method might seem an unnecessary overhead. A good example would be when launching a new thread. This class creates a thread and also contains the code that the thread executes, without the need for creating an additional method for the delegate.
void StartThread()
{
    System.Threading.Thread t1 = new System.Threading.Thread
      (delegate()
            {
                System.Console.Write("Hello, ");
                System.Console.WriteLine("World!");
            });
    t1.Start();
}

The scope of the parameters of an anonymous method is the anonymous-method-block.
It is an error to have a jump statement, such as gotobreak, or continue, inside the anonymous method block whose target is outside the block. It is also an error to have a jump statement, such as gotobreak, or continue, outside the anonymous method block whose target is inside the block.
The local variables and parameters whose scope contain an anonymous method declaration are called outer or captured variables of the anonymous method. For example, in the following code segment, n is an outer variable:
int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };

Unlike local variables, the lifetime of the outer variable extends until the delegates that reference the anonymous methods are eligible for garbage collection. A reference to n is captured at the time the delegate is created.
An anonymous method cannot access the ref or out parameters of an outer scope.
No unsafe code can be accessed within the anonymous-method-block.
The following example demonstrates the two ways of instantiating a delegate:
  • Associating the delegate with an anonymous method.
  • Associating the delegate with a named method (DoWork).
In each case, a message is displayed when the delegate is invoked.
// Declare a delegate
delegate void Printer(string s);

class TestClass
{
    static void Main()
    {
        // Instatiate the delegate type using an anonymous method:
        Printer p = delegate(string j)
        {
            System.Console.WriteLine(j);
        };

        // Results from the anonymous delegate call:
        p("The delegate using the anonymous method is called.");

        // The delegate instantiation using a named method "DoWork":
        p = new Printer(TestClass.DoWork);

        // Results from the old style delegate call:
        p("The delegate using the named method is called.");
    }

    // The method associated with the named delegate:
    static void DoWork(string k)
    {
        System.Console.WriteLine(k);
    }
}

The delegate using the anonymous method is called.
The delegate using the named method is called.

Conclusion


Hopefully this helped clarify delegates, anonymous methods and lambdas, both in terms of their crazy syntax as well as how you can use them within your own code. When you combine this with a solid understanding of generics you end up with some powerful and concise code. You also end up with new ways to solve existing problems, which could otherwise be problematic and ugly. Don’t be afraid to try using some of these solutions within your code. The best way to learn how pieces fit together and to actually try to make something work

Recent Post

how to control duplicate order