Introduction to Delegates
Introduction to Delegates
Fundamentals of Delegates
Introduction
A function is an action whose role can be requested or called anytime, without going through a class as is the case for a method of a class. This concept is supported in the .NET Framework as a delegate and made available to C# (and the other .NET languages).
As you probably know from C#, a class can contain one or more methods used to perform operations. Here is an example:
using System.Web.Mvc; namespace Exercises.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { return View(); } public void Create() { ViewBag.Message = "Actions speak louder than words"; } } }
Such a method must be explicitly called. Here is an example:
using System.Web.Mvc; namespace Exercises.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { Create(); return View(); } public void Create() { ViewBag.Message = "Actions speak louder than words"; } } }
Here is an example of accessing the message in the method:
@{
ViewBag.Title = "Conversations";
}
<p>@ViewBag.Message</p>
This would produce:
Practical Learning: Introducing Delegates
body { padding-top: 150px; background-color: #EEEEEE; } #top-banner { top: 0; left: 0; right: 0; width: 100%; bottom: auto; height: 5.75em; position: absolute; background-color: #192E46; } .centralizer { margin: auto; width: 700px; } .navbar-inverse { background-color: orange; border-color: #080808; } .navbar { border-top: 5px solid #faf76f; border-bottom: 5px solid navy; } .navbar-fixed-top { top: 80px; } .navbar-inverse .navbar-nav > li > a, .navbar-inverse .navbar-nav > li > a:link { color: #faf76f; background-color: transparent; } .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus { color: orange; background-color: #faf76f; } .body-holder { width: 800px; margin: auto; } .col-md-3 { padding-top: 10px; border-radius: 6px; padding-bottom: 10px; background-color: #800000; border: 1px solid #000000; } .jumbotron { padding-top: 3px; border-radius: 10px; background-color: #f1ddca; } .jumbotron h1 { color: #800000; font-size: 43px; } .lead { margin-bottom: 0; } #bottom-banner { left: 0; right: 0; bottom: 0; top: auto; width: 100%; height: 4.15em; position: absolute; background-color: #003366; border-top: 5pt solid black; } #copyright { color: orange; margin-top: 1em; font-weight: 600; font-size: 1.15em; text-align: center; line-height: 1.15em; font-family: Garamond, Georgia, 'Times New Roman', serif; } .topic { float: left } .topic a:link, .topic a:active, .topic a:visited, .topic a:hover { height: 32px; font-size: 12pt; line-height: 26px; margin-left: -10px; padding-left: 20px; text-decoration: none; display: inline-block; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } .topic, .topic a:link, .topic a:active, .topic a:visited, .topic a:hover { width: 190px } .topic a:link { color: #FFFF00 } .topic a:active { color: #CC99FF } .topic a:visited { color: #FFCC99 } .topic a:hover { color: #FFCCFF; display: inline-block; background-color: #ff6a00; outline: 1pt solid #CCFF33; } .small-text { width: 30px; } .left-col { width: 120px } .large { width: 168px } .txtContext { width: 80px } .left-column { width: 200px } .left-text-boxes { width: 100px } .right-label { width: 145px } .horizontal-line { border-bottom: 1px dotted #000000; } .btnLarge { height: 32px; width: 400px; }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace GasUtilityCompany7.Controllers
{
public class EmployeesController : Controller
{
// GET: Employees
public ActionResult Index()
{
return View();
}
// GET: ResetPassword
public ActionResult ResetPassword()
{
return View();
}
}
}
@{ ViewBag.Title = "Employees"; } <h2>Gas Utility Company - Employees Portal</h2> <p>@Html.ActionLink("Reset Employee Account Password", "ResetPassword")</p>
@{ ViewBag.Title = "GUC Home"; } <div class="jumbotron"> <h1>Your Gas Needs With Us</h1> <p class="lead">The Gas Utility Company (GUC) serves the whole Metropolitan area and its vicinity. The company serves both residential and business needs in terms of natural gas.</p> </div> <div class="row"> <div class="col-md-4"> <h2>Employees</h2> <p>If you are an employee, make sure you log in in order to sign your time sheet and review available internal employment.</p> @Html.ActionLink("Employees Portal", "Index", "Employees") </div> <div class="col-md-4"> <h2>Customers</h2> <p>In order to review or pay your bill, you must first log in. If you are not yet a customer, please create an account today.</p> @Html.ActionLink("Customers Topics", "Index", "Customers") </div> <div class="col-md-4"> <h2>Community</h2> <p>This section provides much information about GUC's interactions with its community and its environment.</p> @Html.ActionLink("Community Relations", "Index", "Home") </div> </div>
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Gas Utility Company :: @ViewBag.Title</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") <link rel="stylesheet" type="text/css" href="~/Content/Utilities.css" /> </head> <body> <header id="top-banner"> <p class="text-center"><img src="~/Images/guc.png" alt="Gas Utility Company" width="649" height="74" /></p> </header> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="centralizer"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("GUC Home", "Index", "Home")</li> <li>@Html.ActionLink("Customers", "Index", "Home")</li> <li>@Html.ActionLink("Community", "Index", "Home")</li> <li>@Html.ActionLink("Careers", "Index", "Home")</li> <li>@Html.ActionLink("About GUC", "About", "Home")</li> <li>@Html.ActionLink("Contact Us", "Contact", "Home")</li> </ul> </div> </div> </div> </div> <div class="body-holder"> <div class="col-md-3"> <div class="topic">@Html.ActionLink("Safety", "Index", "Home")</div> <div class="topic">@Html.ActionLink("Outages", "Index", "Home")</div> <div class="topic">@Html.ActionLink("Commercial", "Index", "Home")</div> <div class="topic">@Html.ActionLink("Residential", "Index", "Home")</div> <div class="topic">@Html.ActionLink("Environment", "Index", "Home")</div> <div class="topic">@Html.ActionLink("Services/Appliances", "Index", "Home")</div> <div class="topic">@Html.ActionLink("Community Relations", "Index", "Home")</div> </div> <div class="col-md-9"> @RenderBody() </div> </div> <hr /> <footer id="bottom-banner"> <p id="copyright">© @DateTime.Now.Year - Gas Utility Company</p> </footer> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) </body> </html>
Introduction to Creating a Delegate
The basic formula to create a delegate is:
[options] [modifier(s)] delegate void delegate-name ([formal-parameters]);
You can start with some opions (such as attributes). The modifiers can be one or an appropriate combination of the following keywords: new, public, private, protected, or internal. The delegate keyword is required. A delegae can be any of the types we have used so far. It can also be a type void. The delegate-name must be a valid C# name. The names of delegates follow the rules and suggestions of named of methods.
Because a delegate is some type of a template for a method, you must use parentheses, required for every method. If this method will not take any argument, leave the parentheses empty. Here is an example:
using System.Web;
public delegate string Observation();
public class Sociology
{
}
You can also create a delegate in a file that contains a controller class. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
}
}
As mentioned already, a delegate is primarily a syntax for a method and it is used to refer to an actual method. To use a delegate, you must define a method that would carry an assignment. That method must have the same return type and the same (number of) argument(s), if any. Here is an example:
public delegate void Observation(); public class Sociology { public void Create() { string sentence = "A man with one watch knows what time it is; a man with two watches is never quite sure. - Lee Segall -"; } }
Here is an example of the method created in a controller class:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Exercises.Controllers { public delegate void Observation(); public class ConversationController : Controller { public void Create() { ViewBag.Message = "A man with one watch knows what time it is; a man with two watches is never quite sure. - Lee Segall -"; } } }
Practical Learning: Creating a Delegate
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace GasUtilityCompany7.Controllers
{
public delegate void AccountReset();
public class EmployeesController : Controller
{
// GET: Employees
public ActionResult Index()
{
return View();
}
// GET: ResetPassword
public ActionResult ResetPassword()
{
return View();
}
}
}
Associating a Method to a Delegate
After creating the method, you can associate it to the name of the desired delegate. To do that, where you want to use the method, declare a variable of the type of the delegate. You have two options:
public delegate string Quote(); public class Sociology { public string Create() { return "A man with one watch knows what time it is; a man with two watches is never quite sure. - Lee Segall -"; } public void Publish() { Quote qt = new Quote(Create); } }This example supposed that the class is created outside of any namespace. If the class was created in (a) namespace(s), then you must quelify the names. Here is an example:
@{
Exercises.App_Code.PoliticalScience ps = new Exercises.App_Code.PoliticalScience();
Exercises.App_Code.Quote qt = new Exercises.App_Code.Quote(ps.Create);
}
@{
Sociology socio = new Sociology();
Quote qt = new Quote(socio.Create);
}
public delegate string Quote();
public class Sociology
{
public string Create()
{
return "A man with one watch knows what time it is; a man with two watches is never quite sure. - Lee Segall -";
}
public void Publish()
{
Quote qt = Create;
}
}
@{
Sociology socio = new Sociology();
Quote qt = socio.Create;
}
If the delegate and/or class belong(s) to (a) namespace(s), make sure you qualify it/them. Here is and example:
@{
Exercises.App_Code.PoliticalScience ps = new Exercises.App_Code.PoliticalScience();
Exercises.App_Code.Quote qt = ps.Create;
}
Practical Learning: Associating a Method to a Delegate
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace GasUtilityCompany7.Controllers
{
public delegate void AccountReset();
public class EmployeesController : Controller
{
// GET: Employees
public ActionResult Index()
{
return View();
}
// GET: ResetPassword
public ActionResult ResetPassword()
{
return View();
}
public void ChangingCredentials()
{
int digits = 0, symbols = 0, lowercase = 0, uppercase = 0;
string strNewPassword = "N@t0ralS3creT#48";
int length = strNewPassword.Length;
for (int i = 0; i < length; i++)
{
if (Char.IsDigit(strNewPassword[i]))
{
digits++;
}
if (Char.IsSymbol(strNewPassword[i]) || Char.IsPunctuation(strNewPassword[i]))
{
symbols++;
}
if (Char.IsLower(strNewPassword[i]))
{
lowercase++;
}
if (Char.IsUpper(strNewPassword[i]))
{
uppercase++;
}
}
ViewBag.Digits = digits;
ViewBag.Characters = length;
ViewBag.Symbols = symbols;
ViewBag.Lowercase = lowercase;
ViewBag.Uppercase = uppercase;
}
}
}
Accessing a Delegate
Once you have associated a method to a delegate variable, you can use the delegate variable as if it were a defined method. That is, you can call it as you would proceed for a normal method. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
Observation quote = new Observation(Hold);
quote();
return View();
}
public void Hold()
{
ViewBag.Message "A man with one watch knows what time it is; a man with two watches is never quite sure. - Lee Segall -";
}
}
}
If you are working in a webpage, you can precede the call with @. Here is an example:
@{
ViewBag.Title = "Conversations";
}
<p>@@ViewBag.Message</p>
Practical Learning: Accessing a Delegate
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace GasUtilityCompany7.Controllers
{
public delegate void AccountReset*(;
public class EmployeesController : Controller
{
// GET: Employees
public ActionResult Index()
{
return View();
}
// GET: ResetPassword
public ActionResult ResetPassword()
{
AccountReset change = new AccountReset(ChangingCredentials);
change();
return View();
}
public void ChangingCredentials()
{
. . . No Change
}
}
}
@{ ViewBag.Title = "Reset Password"; } <h2>Gas Utility Company</h2> <h3>Reset Password</h3> <div class="horizontal-line"></div> <h4>Suggested Password Summary</h4> <p>The suggested password contains:</p> <ul> <li>@ViewBag.Characters letters and/or symbols</li> <li>@ViewBag.Digits digits</li> <li>@ViewBag.Symbols symbols</li> <li>@ViewBag.Uppercase uppercase letters</li> <li>@ViewBag.Lowercase lowercase letters</li> </ul>
Introductory Topics on Delegates
A Static Method for a Delegate
If the class that contains the method is static, you must define the method as static. Even if that class is not static, you can still define the method as static. Here is an example of such a method:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
public static void Create()
{
}
}
}
In both cases, you would not need to declare the variable first. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
Observation quote = Create;
return View();
}
public static void Create()
{
}
}
}
An Anonymous Delegate
In the above examples, we had to create a method that would be associated with a delegate. As an alternative, you can first create a delegate. Here is an example:
namespace Exercises.App_Code
{
public delegate void Observation();
}
Then, when you need to use it, create a type of local implementation of a method and use it. In other words, you don’t have to define a formal method that would initialize the delegate. Such a method is referred to as anonymous.
To create an anonymous method, declare a variable for the delegate and assign it the delegate keyword as if it were a method. That is, followed by parentheses and curly brackets that would represent the body of the method. In the body of the anonymous method, do whatever you want. Here is an example:
p@{ Exercises.Controllers.Observation example = delegate () { return "If reality TV has taught us anything, it's that you can't keep people with no shame down. - 30 Rock (NBC) -"; }; }
Once you have done this, you can then call the delegate variable as if it were a normal method. Here is an example:
@{
ViewBag.Title = "Conversations";
}
@{
Exercises.Controllers.Observation remark = delegate ()
{
ViewBag.Message = "If reality TV has taught us anything, it's that you can't keep people with no shame down. - 30 Rock (NBC) -";
};
}
@{
remark();
}
Practical Learning: Creating and Using an Anonymous Delegate
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace GasUtilityCompany7.Controllers { public delegate void AccountReset(); public class EmployeesController : Controller { // GET: Employees public ActionResult Index() { return View(); } // GET: ResetPassword public ActionResult ResetPassword() { return View(); } } }
@{
ViewBag.Title = "Reset Password";
}
<h2>Gas Utility Company</h2>
<h3>Reset Password</h3>
<div class="horizontal-line"></div>
@{
GasUtilityCompany7.Controllers.AccountReset change = delegate ()
{
int digits = 0;
int symbols = 0;
int lowercase = 0;
int uppercase = 0;
string strNewPassword = "N@t0ralS3creT#48";
int length = strNewPassword.Length;
for (int i = 0; i < length; i++)
{
if (Char.IsDigit(strNewPassword[i]))
{
digits++;
}
if (Char.IsSymbol(strNewPassword[i]) || Char.IsPunctuation(strNewPassword[i]))
{
symbols++;
}
if (Char.IsLower(strNewPassword[i]))
{
lowercase++;
}
if (Char.IsUpper(strNewPassword[i]))
{
uppercase++;
}
}
ViewBag.Digits = digits;
ViewBag.Characters = length;
ViewBag.Symbols = symbols;
ViewBag.Lowercase = lowercase;
ViewBag.Uppercase = uppercase;
ViewBag.Password = strNewPassword;
};
}
<div class="horizontal-line"></div>
@{
change();
}
@using (Html.BeginForm())
{
<table>
<tr>
<td class="left-col">New Password:</td>
<td><input type="text" name="txtNewPassword" value=@ViewBag.Password /></td>
<td><input type="text" name="txtCharacters" class="small-text" value=@ViewBag.Characters /> Characters</td>
</tr>
<tr>
<td>Confirm Password:</td>
<td><input type="text" name="txtConfirmPassword" , value="" /></td>
<td> </td>
</tr>
</table>
<table>
<tr>
<td class="left-col"> </td>
<td class="large"><input type="text" name="txtLowercase" class="small-text" , value=@ViewBag.Lowercase /> Lowercase Letters</td>
<td><input type="text" class="small-text" name="txtUppercase" value=@ViewBag.Uppercase /> Uppercase Letters</td>
</tr>
<tr>
<td class="left-col"> </td>
<td><input type="text" name="txtDigits" , class="small-text" value=@ViewBag.Digits /> Digits</td>
<td><input type="text" name="txtSymbols" value=@ViewBag.Symbols class="small-text" /> Symbols</td>
</tr>
</table>
<div class="horizontal-line"></div>
<p class="text-center"><input type="submit" name="btnSubmit" value="Submit" class="btnLarge" /></p>
}
@{ ViewBag.Title = "Reset Password"; } <h2>Gas Utility Company</h2> <h3>Reset Password</h3> <div class="horizontal-line"></div> @{ GasUtilityCompany7.Controllers.AccountReset change = delegate () { int length = 0; int digits = 0; int symbols = 0; int lowercase = 0; int uppercase = 0; string strNewPassword = string.Empty; strNewPassword = Request["txtNewPassword"]; length = strNewPassword.Length; for (int i = 0; i < length; i++) { if (Char.IsDigit(strNewPassword[i])) { digits++; } if (Char.IsSymbol(strNewPassword[i]) || Char.IsPunctuation(strNewPassword[i])) { symbols++; } if (Char.IsLower(strNewPassword[i])) { lowercase++; } if (Char.IsUpper(strNewPassword[i])) { uppercase++; } } ViewBag.Digits = digits; ViewBag.Characters = length; ViewBag.Symbols = symbols; ViewBag.Lowercase = lowercase; ViewBag.Uppercase = uppercase; ViewBag.Password = strNewPassword; }; } <div class="horizontal-line"></div> @{ if (IsPost) { change(); } } @using (Html.BeginForm()) { <table> <tr> <td class="left-col">New Password:</td> <td><input type="text" name="txtNewPassword" value=@ViewBag.Password /></td> <td><input type="text" name="txtCharacters" class="small-text" value=@ViewBag.Characters /> Characters</td> </tr> <tr> <td>Confirm Password:</td> <td><input type="text" name="txtConfirmPassword" , value="" /></td> <td> </td> </tr> </table> <table> <tr> <td class="left-col"> </td> <td class="large"><input type="text" name="txtLowercase" class="small-text" , value=@ViewBag.Lowercase /> Lowercase Letters</td> <td><input type="text" class="small-text" name="txtUppercase" value=@ViewBag.Uppercase /> Uppercase Letters</td> </tr> <tr> <td class="left-col"> </td> <td><input type="text" name="txtDigits" , class="small-text" value=@ViewBag.Digits /> Digits</td> <td><input type="text" name="txtSymbols" value=@ViewBag.Symbols class="small-text" /> Symbols</td> </tr> </table> <div class="horizontal-line"></div> <p class="text-center"><input type="submit" name="btnSubmit" value="Submit" class="btnLarge" /></p> }
The Lambda Operator
You can also create an anonymous method using an operator called lambda and represented by =>. From our example above, to use the lambda operator to create an anonymous method, omit the delegate keyword and follow the parentheses by the operator. Here is an example:
@{
ViewBag.Title = "Conversations";
}
@{
Exercises.App_Code.Quote example = () =>
{
return "I feel like I've got a guest come to my house, unexpected, stayed three weeks uninvited, and then they start complaining about the food. - Robert Blasier - Attorney at Law -";
};
}
<p>@example()</p>
Practical Learning: Creating and Using a Lambda Expression
@{
ViewBag.Title = "Reset Password";
}
<h2>Gas Utility Company</h2>
<h3>Reset Password</h3>
<div class="horizontal-line"></div>
@{
GasUtilityCompany7.Controllers.AccountReset change = () =>
{
. . . No Change
};
}
<div class="horizontal-line"></div>
@{
if (IsPost)
{
change();
}
}
@using (Html.BeginForm())
{
. . . No Change
}
Delegates Compositions
Adding Delegates
A delegate can be added to another delegate using the + operation. This is referred to as composition. This is done by adding one delegate variable to another as in result = a + b. After doing this, to access the action produced, call the variable as if it were a method, as in result(). In the same way, you can add many delegates as in result = a + b + c. or more. You can call the variable like a method as in result().
Practical Learning: Adding Delegates
@{ ViewBag.Title = "Reset Password"; } <h2>Gas Utility Company</h2> <h3>Reset Password</h3> <div class="horizontal-line"></div> @{ string[] recentPasswords = new string[5] { "Password1", "Password2", "Password3", "Password4", "Password5" }; GasUtilityCompany7.Controllers.AccountReset change = () => { int length = 0; int digits = 0; int symbols = 0; int lowercase = 0; int uppercase = 0; string strNewPassword = string.Empty; strNewPassword = Request["txtNewPassword"]; length = strNewPassword.Length; for (int i = 0; i < length; i++) { if (Char.IsDigit(strNewPassword[i])) { digits++; } if (Char.IsSymbol(strNewPassword[i]) || Char.IsPunctuation(strNewPassword[i])) { symbols++; } if (Char.IsLower(strNewPassword[i])) { lowercase++; } if (Char.IsUpper(strNewPassword[i])) { uppercase++; } } ViewBag.Digits = digits; ViewBag.Symbols = symbols; ViewBag.Characters = length; ViewBag.Lowercase = lowercase; ViewBag.Uppercase = uppercase; ViewBag.Password = strNewPassword; }; GasUtilityCompany7.Controllers.AccountReset comparison = () => { bool pwdFound = false; string strNewPassword = string.Empty; string strConfirmPassword = string.Empty; strNewPassword = Request["txtNewPassword"]; for (int i = 0; i < recentPasswords.Length; i++) { if(recentPasswords[i] == strNewPassword) { pwdFound = true; } } if(pwdFound == true) { ViewBag.ErrorMessage = "That password was previously used. Please try another password."; } }; } <div class="horizontal-line"></div> @{ if (IsPost) { GasUtilityCompany7.Controllers.AccountReset combination = change + comparison; combination(); } } @using (Html.BeginForm()) { <table> <tr> <td class="left-col">New Password:</td> <td><input type="text" name="txtNewPassword" value=@ViewBag.Password /></td> <td><input type="text" name="txtCharacters" class="small-text" value=@ViewBag.Characters /> Characters</td> </tr> <tr> <td>Confirm Password:</td> <td><input type="text" name="txtConfirmPassword" , value="" /></td> <td> </td> </tr> </table> <table> <tr> <td class="left-col"> </td> <td class="large"><input type="text" name="txtLowercase" class="small-text" , value=@ViewBag.Lowercase /> Lowercase Letters</td> <td><input type="text" class="small-text" name="txtUppercase" value=@ViewBag.Uppercase /> Uppercase Letters</td> </tr> <tr> <td class="left-col"> </td> <td><input type="text" name="txtDigits" , class="small-text" value=@ViewBag.Digits /> Digits</td> <td><input type="text" name="txtSymbols" value=@ViewBag.Symbols class="small-text" /> Symbols</td> </tr> </table> <div class="horizontal-line"></div> <p class="text-center"><input type="submit" name="btnSubmit" value="Submit" class="btnLarge" /></p> @ViewBag.ErrorMessage }
Delegates and Compound Addition
Besides the regular addition, delegates also support the compound addition performed using the += operator. It works exactly as in C# arithmetic. This means that you can first add a delegate to a variable and assign the result to the variable as follows:
result = first;
result = result + second;
As an alternative, you can use the += operator between the variable and the right operand. This can be done as follows:
result = first;
result += second;
Practical Learning: Performing a Compound Addition on Delegates
@{ ViewBag.Title = "Reset Password"; } <h2>Gas Utility Company</h2> <h3>Reset Password</h3> <div class="horizontal-line"></div> @{ string[] recentPasswords = new string[5] { "P@ssw0rdAgent#1", "P@ssw0rdAgent#2", "P@ssw0rdAgent#3", "P@ssw0rdAgent#4", "P@ssw0rdAgent#5" }; GasUtilityCompany7.Controllers.AccountReset change = () => { int length = 0; int digits = 0; int symbols = 0; int lowercase = 0; int uppercase = 0; string strNewPassword = string.Empty; strNewPassword = Request["txtNewPassword"]; length = strNewPassword.Length; for (int i = 0; i < length; i++) { if (Char.IsDigit(strNewPassword[i])) { digits++; } if (Char.IsSymbol(strNewPassword[i]) || Char.IsPunctuation(strNewPassword[i])) { symbols++; } if (Char.IsLower(strNewPassword[i])) { lowercase++; } if (Char.IsUpper(strNewPassword[i])) { uppercase++; } } ViewBag.Digits = digits; ViewBag.Symbols = symbols; ViewBag.Characters = length; ViewBag.Lowercase = lowercase; ViewBag.Uppercase = uppercase; ViewBag.Password = strNewPassword; }; GasUtilityCompany7.Controllers.AccountReset comparison = () => { bool pwdFound = false; string strNewPassword = string.Empty; string strConfirmPassword = string.Empty; strNewPassword = Request["txtNewPassword"]; for (int i = 0; i < recentPasswords.Length; i++) { if (recentPasswords[i] == strNewPassword) { pwdFound = true; } } if (pwdFound == true) { ViewBag.ErrorMessage = "That password was previously used. Please try another password."; } }; GasUtilityCompany7.Controllers.AccountReset validation = () => { int digits = 0; int symbols = 0; int lowercase = 0; int uppercase = 0; string strNewPassword = Request["txtNewPassword"]; int length = strNewPassword.Length; for (int i = 0; i < length - 1; i++) { if (Char.IsDigit(strNewPassword[i])) { digits++; } if (Char.IsSymbol(strNewPassword[i]) || Char.IsPunctuation(strNewPassword[i])) { symbols++; } if (Char.IsLower(strNewPassword[i])) { lowercase++; } if (Char.IsUpper(strNewPassword[i])) { uppercase++; } } if( length < 8 ) { ViewBag.ErrorMessage = "Your password does not meet the requirements (a password must have at least 8 characters)."; } else if( lowercase < 2 ) { ViewBag.ErrorMessage = "The password you provided is not valid (the password must include at least 2 lowercase letters)."; } else if( uppercase < 2 ) { ViewBag.ErrorMessage = "The password you typed doesn't meet the requirement rules (a password must include at least 2 uppercase letters)."; } else if( digits < 2 ) { ViewBag.ErrorMessage = "Your password is not meeting the credential rules (the password must have at least 2 digits)."; } else if (symbols < 2) { ViewBag.ErrorMessage = "Your password doesn't meet the required rules (a password must have at least 2 non-alphabetical symbols)."; } }; } <div class="horizontal-line"></div> @{ if (IsPost) { GasUtilityCompany7.Controllers.AccountReset combination = change; combination += comparison; combination += validation; combination(); } } @using (Html.BeginForm()) { <table> <tr> <td class="left-col">New Password:</td> <td><input type="text" name="txtNewPassword" value=@ViewBag.Password /></td> <td><input type="text" name="txtCharacters" class="small-text" value=@ViewBag.Characters /> Characters</td> </tr> <tr> <td>Confirm Password:</td> <td><input type="text" name="txtConfirmPassword" , value="" /></td> <td> </td> </tr> </table> <table> <tr> <td class="left-col"> </td> <td class="large"><input type="text" name="txtLowercase" class="small-text" , value=@ViewBag.Lowercase /> Lowercase Letters</td> <td><input type="text" class="small-text" name="txtUppercase" value=@ViewBag.Uppercase /> Uppercase Letters</td> </tr> <tr> <td class="left-col"> </td> <td><input type="text" name="txtDigits" , class="small-text" value=@ViewBag.Digits /> Digits</td> <td><input type="text" name="txtSymbols" value=@ViewBag.Symbols class="small-text" /> Symbols</td> </tr> </table> <div class="horizontal-line"></div> <p class="text-center"><input type="submit" name="btnSubmit" value="Submit" class="btnLarge" /></p> @ViewBag.ErrorMessage }
Delegates and Parameters
A Delegate that Uses a Parameter
If you want to use a method that takes arguments and associate it to a delegate, when creating the delegate, provide the necessary parameter(s) in its parentheses. Here is an example of a delegate that takes a parameter:
delegate void Observation(string arg);
When defining the associated method, make it take the same number and type(s) of parameters. Here is an example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation(string msg);
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
public void Create(string say)
{
}
}
}
To associate the method to the delegate, declare a variable for the delegate and initialize it with the method. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation(string msg);
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
Observation quote = new Observation(Create);
return View();
}
public void Create(string say)
{
ViewBag.Message = say;
}
}
}
To use the variable, when calling it, pass an argument. Here is an example:
using System;
using System.Web.Mvc;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
namespace Exercises.Controllers
{
public delegate void Observation(string msg);
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
Observation conference = Create;
Observation quote = new Observation(Create);
quote("Les dances à la gloire de la fornication.");
return View();
}
public void Create(string say)
{
ViewBag.Message = say;
}
}
}
Here is an example of accessing the value of the operation from a webpage:
@{
ViewBag.Title = "Conversations";
}
<p>@@ViewBag.Message</p>
In the same way, you can declare various variables of the same delegate. Here are two examples:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation(string msg);
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
Observation conference = Create;
Observation quote = new Observation(Create);
return View();
}
public void Create(string say)
{
ViewBag.Message = say;
}
}
}
Notice that only the name of the method is used. No parentheses are added and the arguments are not passed. To actually use the delegate, when calling it, add the parentheses to it and in the parentheses, provide a value for each argument. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation(string msg);
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
string strMessage = "A man with one watch knows what time it is; a man with two watches is never quite sure. - Lee Segall -";
Observation conference = Create;
Observation description = new Observation(Create);
conference(strMessage);
description("Chemistry is the study of matter. Matter is the " +
"building block of anything in the environment, that is, anything that " +
"occupies any form of space, anything that can be seen or is hidden to " +
"the human eye.");
return View();
}
public void Create(string say)
{
ViewBag.Message = say;
}
}
}
In the same way, you can use any type of parameter.
A Delegate with Many Parameters
A delegate can use more than one parameter. Remember that, when creating the delegate, pass the same number and type(s) of parameter(s). Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Operation(string n, double x, char c, double y);
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
}
}
Remember that a method that will be associated to the delegate must take the same types and order of parameters. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Operation(string n, double x, char c, double y);
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
public void Add(string name, double first, char oper, double second)
{
double result = first + second;
ViewBag.Addition = result.ToString();
}
}
}
When calling the delegate from a variable, pass the appropriate number and type(s) of argument(s):
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Operation(string n, double x, char c, double y);
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
Operation Number = Add;
Operation Times = new Operation(Multiply);
Number("Addition", 2946.24, '+', 8253.44);
Times("Multiplication", 208.73, '*', 95.86);
return View();
}
public void Add(string name, double first, char oper, double second)
{
double result = first + second;
ViewBag.Addition = result.ToString();
}
public void Multiply(string identification, double number, char symbol, double factor)
{
double result = number * factor;
ViewBag.Multiplication = result.ToString();
}
}
}
Parameterized Delegates and Lambda Expressions
You can create an anonymous method for a delegate that takes one or more parameters. Of course, you must first create a delegate. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Description(string n, int s);
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
}
}
Remember that, to create an anonymous delegate, you can use the delegate keyword. Here is an example:
@{
Exercises.Controllers.Description sayit = delegate (string strName, string units, int items)
{
ViewBag.Message = "A " + strName + " uses " + items + " " + units;
};
}
When calling the delegate variable, in its parentheses, pass each argument as the same type and order as a parameter of the delegate. Here are examples:
@{ ViewBag.Title = "Descriptions"; } @{ Exercises.Controllers.Description sayit = delegate (string strName, string units, int items) { ViewBag.Message = "A " + strName + " uses " + items + " " + units; }; } @{ sayit("square", "sides", 4); } <p>@ViewBag.Message</p> @{ sayit("water molecule", "atoms", 3); <p>@ViewBag.Message</p> }
Instead of the delegate keyword, you can define an anonymous method using the lambda operator. In this case, in the parentheses of the lambda expression, enter the data type of the argument followed by its name. In the body of the anonymous method, use the argument or ignore it as you see fit. After defining the method, you can call it like a normal method. Here is an example:
@{
ViewBag.Title = "Conversations";
}
@{
Exercises.Controllers.Description sayit = (string strName, string units, int items) =>
{
ViewBag.Message = "A " + strName + " uses " + items + " " + units;
};
}
@{
sayit("square", "sides", 4);
}
<p>@ViewBag.Message</p>
@{
sayit("water molecule", "atoms", 3);
<p>@ViewBag.Message</p>
}
In our example, we specified the type of the parameter. If you want, you can let the compiler figure out the type of argument. In this case, pass only the name of the parameter and not its type. Here is an example:
@{
ViewBag.Title = "Conversations";
}
@{
Exercises.Controllers.Description sayit = (strName, units, items) =>
{
ViewBag.Message = "A " + strName + " uses " + items + " " + units;
};
}
@{
sayit("square", "sides", 4);
}
<p>@ViewBag.Message</p>
@{
sayit("water molecule", "atoms", 3);
<p>@ViewBag.Message</p>
}
A Delegate as a Type
Returning a Delegate from a Method
Because a delegate is a type, you can create a method that returns it. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
public Observation Produce()
{
}
}
}
In the body of the method, do what you want. At the end of the method, make sure you return a value or object that is the type of the delegate. For example, or at a minimum, you can declare a variable of the delegate and initialize it as we have done so far, then return that variable. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
public void Hold()
{
}
public Observation Produce()
{
Observation quote = new Observation(Hold);
return quote;
}
}
}
To use the method, you can declare a variable of the type of the delegate and you can initialize it with a call to the method that returns the delegate. You can then call the new variable as a method. Here ia an example:
using System;
using System.Web.Mvc;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
Observation obs = Produce();
obs();
return View();
}
public void Hold()
{
ViewBag.Message = "A man with one watch knows what time it is; a man with two watches is never quite sure. - Lee Segall -";
}
public Observation Produce()
{
Observation quote = new Observation(Hold);
return quote;
}
}
}
Once again, you can access the value that was processed in the class from a webpage:
@{
ViewBag.Title = "Conversations";
}
<p>@@ViewBag.Message</p>
Passing a Delegate (Method) as Parameter
Most languages don't allow pass a method (called function) as argument. Delegates provide an alternative. Because a delegate is an object, or rather treated as such, it can be used as a parameter.
To start, you must have or create a delegate that has the syntax of the method you want to use. Here is an example of a delegate for a method that simply adds two numbers:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
}
}
Once you have the delegate, you can create a method with the same syntax but that performs the action you want. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
public void Hold()
{
}
}
}
After doing this, you can create a method to which you would pass the delegate as parameter. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
public void Hold()
{
}
public void Create(Observation speech)
{
}
}
}
In the body of the method, call the delegate as a mehod. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
public void Hold()
{
}
public void Create(Observation speech)
{
speech();
}
}
}
When you call the method that takes a delegate as parameter, pass the name of the method that is associated to the delegate. This can be done in a class as follows:
Alternative, you can keep one backslash in each placeholder but precede the value of the string with the @ symbol. Here is an example:
using System.Web.Mvc;
namespace Exercises.Controllers
{
public delegate void Observation();
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
Create(Hold);
return View();
}
public void Hold()
{
ViewBag.Message = "A man with one watch knows what time it is; a man with two watches is never quite sure. - Lee Segall -";
}
public void Create(Observation speech)
{
speech();
}
}
}
Here is an example of accessing the value of the above scenario in a webpage:
@{
ViewBag.Title = "Conversations";
}
<p>@ViewBag.Message</p>
A Method as Parameter in a Lambda Expression
Instead of creating a formal method that would be associated with a delegate passed as parameter, you can define a lambda expression in the place where the delegate variable is passed as argument.
Delegates and Classes
So far, we involved only primitive types with delegates, especially when it came to parameters. Indeed, any type of value can be passed to a delegate and subsequently to its associated method(s). You can use any appropriate class. For example, you can create your own class, but as you know it already, the .NET Framework provide a large library of classes you can use.
|
||
Previous | Copyright © 2008-2019, FunctionX | Next |
|