Introduction to Actions

Overview

Because the concepts of delegates are very important, valuable, and useful in programming, the .NET Framework provides a special delegate, that is, pre-built. This delegate is named Action. The Action delegate is provided in many (overloaded) versions so that you can find a syntax that suits any need. This means that in many cases, instead of creating your delegate from scratch, you can use the Action delegate instead.

A Simple Action

As we saw in our introduction, the simplest delegate is a method that doesn't use any parameter. Here is the example:

using System.Web.Mvc;

namespace Exercises.Controllers
{
    public delegate void Observation();

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Observation quote = new Observation(HoldConference);

            quote();

            return View();
        }

        public void HoldConference()
        {
            ViewBag.Message = "There are known knowns. These are things we know that we know. " +
		                      "There are known unknowns. That is to say, there are things that we know we don't know. " +
    		                  "But there are also unknown unknowns. There are things we don't know we don't know. - Donald Rumsfeld -";
   	    }
    }
}

This was an example of accessing the value of the above code in a webpage:

@{
    ViewBag.Title = "Social Science";
}

<p>@ViewBag.Message</p>

This would produce:

To support delegates that don't use any parameters, the .NET Framework provides the following version of the Action delegate:

public delegate void Action()

Based on this version of the Action delegate, you don't have to first create a delegate. In the section where you declare a variable for the delegate, use Action. This can be done as follows:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Action quote = new Action(HoldConference);

            quote();

            return View();
        }

        public void HoldConference()
        {
            ViewBag.Message = "There are known knowns. These are things we know that we know. " +
                              "There are known unknowns. That is to say, there are things that we know we don't know. " +
                              "But there are also unknown unknowns. There are things we don't know we don't know. - Donald Rumsfeld -";
        }
    }
}

You don't need to use the new operator to initialize the variable. This means that you can omit calling Action() as a constructor. Therefore, the above code can be written as follows:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            Action quote = HoldConference;

            quote();

            return View();
        }

        public void HoldConference()
        {
            ViewBag.Message = "There are known knowns. These are things we know that we know. " +
                              "There are known unknowns. That is to say, there are things that we know we don't know. " +
                              "But there are also unknown unknowns. There are things we don't know we don't know. - Donald Rumsfeld -";
        }
    }
}

Actions and Anonymous Methods

Action delegates support anonymous methods. The anonymous delegate is created in the same way done for regular delegates. That is, initialyze the Action variable with the delegate keyword, the parentheses, and the body of the method in curly brackets. Here is an example:

using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Action elementaryAlgebra = delegate ()
            {
                Random rndNumber = new Random();
                int number1 = rndNumber.Next(0, 20);
                int number2 = rndNumber.Next(0, 20);
                int total = number1 + number2;

                Response.Write("<p style='font-size: 64px;'>" + number1 + " + " + number2 + " = " + total + "</p>");
            };

            elementaryAlgebra();

            return View();
        }
    }
}

Actions and Lambda Expressions

Like regular delegates, actions support lambda expressions. To apply a lambda expression to an action delegate, initialize the Action variable with empty parentheses, the => operator, and the body of the method. Here is an example:

using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Action elementaryAlgebra = () =>
            {
                Random rndNumber = new Random();
                int number1 = rndNumber.Next(0, 20);
                int number2 = rndNumber.Next(0, 20);
                int total = number1 + number2;

                Response.Write("<p style='font-size: 64px;'>" + number1 + " + " + number2 + " = " + total + "</p>");
            };

            elementaryAlgebra();

            return View();
        }
    }
}

A Delegate With a Parameter

We saw that a delegate can use a parameter. In fact, the Action delegate is created as generic. To support the ability to apply a parameter to a delegate, the .NET Framework provides an Action delegate that uses the following syntax:

public delegate void Action<in T>(T obj)

The parameter can be any type, such as a primitive type or a string. When declaring the variable, to indicate that the delegate is using a parameter, use Action<>. Include the parameter type between < and >. Here is an example:

using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            Action<string> quote = new Action<string>(Create);

            return View();
        }

        public void Create(string say)
        {
            ViewBag.Message = say;
        }
    }
}

You can omit the second Action<string>. Once again, when calling the method, pass an appropriate argument. Here is an example:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            Action<string> quote = Create;

            quote("Ces dances à la gloire de la fornication.");

            return View();
        }

        public void Create(string say)
        {
            ViewBag.Message = say;
        }
    }
}

The value would be accessed in the webpage the same way done previously:

@{
    ViewBag.Title = "Conversations";
}

<p>@ViewBag.Message</p>

An Action Delegate With Many Parameters

The Action delegate can use different numbers and types of parameters. To support this, the .NET Framework provides 17 versions of the Action delegate ranging from one that doesn’t use any parameter to one that takes 16 arguments. To use one of them, declare a variable of type Action<>. Between < and >, enter the types separated by commans. Initialize the variable with a method that use the same number or ordinal types of parameters.

An Action Delegate as a Type

Returning an Action

You can create a method that returns an Action delegate. As seen for formal delegates, when creating the method, set its return type as Action. In the body of the method, do what you want. Before the end of the method, return an object of the Action type. One solution is to declare a variable of Action type and initialize it appropriately. before calling the method, you can declare a variable and assign the Action method to it. Then call that last variable as if it were a method. Here is an example:

using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Action operation = Doubler();

            operation();

            return View();
        }

        public Action Doubler()
        {
            Action times = new Action(Multiplication);

            return times;
        }

        private void Multiplication()
        {
            Random rndNumber = new Random();
            int number1 = rndNumber.Next(0, 10);
            int number2 = rndNumber.Next(0, 10);
            int total = number1 * number2;

            Response.Write("<p style='font-size: 64px;'>" + number1 + " * " + number2 + " = " + total + "</p>");
        }
    }
}

In the same way, a method can return a collection or an array of Action delegates.

An Action as Parameter

To create a method that uses a parameter of type Action, precede that name of the parameter with Action. Here is an example:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            return View();
        }

        public void Create(Action speech)
        {
            
        }
    }
}

In the same way, as opposed to passing it by itself, an Action delegate can be passed as argument along with other (types of) parmeters. In the body of the method, ignore or use the Action parameter. Probably the simplest way to use it is to call it as a method. Here is an example:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            return View();
        }

        public void Create(Action speech)
        {
            speech();
        }
    }
}

When calling the method, you can pass the name of a method that uses the same syntax as the type of Action that was passed as parameter (remember that the .NET Framework provides various syntaxes for actions). Here is an example:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            Create(Hold);

            return View();
        }

        public void Hold()
        {
            ViewBag.Message = "People who live in glass houses should not throw stones";
        }

        public void Create(Action speech)
        {
            speech();
        }
    }
}

.NET Function Delegates

Introduction

An Action is a delegate for a method that doesn’t produce a value. A function is an action that produces or returns a value. At a minimum, a function doesn't use any parameter.

Although you can create your own function delegates , to provide you a faster technique, the .NET Framework provides a special delegate named Func. It uses a generic format as in Func<>.

Web Project: School UniCorp

We are starting a web project for a company named School UniCorp. This is a fictitious company that makes and sells school uniforms. As we start, the company makes shirts and pants and sells them at fixed prices. As we move on in our lessons, we will see how the business changes (we will consider shirts and pants sizes, and different prices).

Practical LearningPractical Learning: Introducing Fuction Delegates

  1. Start Microsoft Visual Studio
  2. On the main menu, click File -> New -> Project...
  3. In the New Project dialog box, click ASP.NET Web Application (.NET Framework) and change the Name to SchoolUniCorp1
  4. Cclick OK
  5. In the New ASP.NET Web Application dialog box, click the MVC icon and click OK
  6. In the Solution Explorer, right-click Content -> Add -> New Item...
  7. In the left frame, click Web and, in the middle frame, click Style Sheet
  8. Change the Name to SchoolUniCorp
  9. Click Add
  10. Add some styles as follows:
    body {
    }
    
    .bottom-border {
        font-weight: bold;
        border-bottom: 1px solid black;
    }
    
    .sh-border {
        width: 400px;
        border-bottom: 3px solid black;
    }
    
    .lowest-border { border-bottom: 3px solid black; }
    .caption-cell  { width: 140px; }
    .control-cell  { width: 100px; }
    .large-cell    { width: 400px; }
  11. In the Solution Explorer, expand Controllers and double-click HomeController.cs to open it
  12. Change the document as follows:
    using System.Web.Mvc;
    
    namespace SchoolUniCorp1.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult About()
            {
                ViewBag.Message = "Your application description page.";
    
                return View();
            }
    
            public ActionResult Contact()
            {
                ViewBag.Message = "Your contact page.";
    
                return View();
            }
    
            public ActionResult CustomerOrderStartUp()
            {
                return View();
            }
    
            public ActionResult CustomerOrderPreparation(string QuantityShirts, string QuantityPants)
            {
                return View();
            }
        }
    }
  13. In the Solution Explorer, expand Views, expand Shared and double-click _Layout.cshtml
  14. Create a link to the style sheet document created earlier:
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>School UniCorp :: @ViewBag.Title - My ASP.NET Application</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    <link rel="stylesheet" type="text/css" href="~/Content/SchoolUniCorp.css" />
    </head>
    <body>
        <div class="navbar navbar-inverse navbar-fixed-top">
            <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>
                    @Html.ActionLink("School UniCorp", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li>@Html.ActionLink("Home", "Index", "Home")</li>
                        <li>@Html.ActionLink("About", "About", "Home")</li>
                        <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                    </ul>
                    @Html.Partial("_LoginPartial")
                </div>
            </div>
        </div>
        <div class="container body-content">
            @RenderBody()
            <hr />
            <footer>
                <p>&copy; @DateTime.Now.Year - School UniCorp</p>
            </footer>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>
  15. In the Solution Explorer, under Views, right-click Home -> Add -> New Scaffoled Item...
  16. In the middle frame of the Add Scaffold dialog box, click MVC 5 View and click Add
  17. Type the View Name as CustomerOrderStartUp
  18. Click Add
  19. Change the code as follows:
    @{
        ViewBag.Title = "Customer Order Start-Up";
    }
    
    <h2>Customer Order Start-Up</h2>
    
    @using (Html.BeginForm("CustomerOrderPreparation", "Home", FormMethod.Post))
    {
        <table>
            <tr>
                <td class="bottom-border caption-cell">&nbsp;</td>
                <td class="bottom-border control-cell bold">Quantity</td>
                <td class="bottom-border bold">Unit Price</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts:</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirts", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("UnitPriceShirts", "15.00", new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border control-cell bold">Pants:</td>
                <td class="bottom-border">@Html.TextBox("QuantityPants", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("UnitPricePants", "20.00", new { style = "width: 80px" })</td>
            </tr>
        </table>
        <hr />
        <table>
            <tr>
                <td class="caption-cell">&nbsp;</td>
                <td><input type="submit" name="btnPrepareCustomerOrder" value="Prepare Customer Order" /></td>
            </tr>
        </table>
    }
  20. To execute the project, on the main menu, click Debug -> Start Without Debugging:

    Introducing Fuction Delegates

  21. Close the browser and return to your programming environment

A Simple Function Delegate

Consider the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public delegate double Evaluation();

    public class SalaryEvaluationController : Controller
    {
        // GET: SalaryEvaluation
        public ActionResult Index()
        {
            Evaluation eval = new Evaluation(Calculate);

            ViewBag.WeeklySalary = eval().ToString("F");


            return View();
        }

        public double Calculate()
        {
            double hSalary = 25.75;
            double tWorked = 38.50;

            double wSalary = hSalary * tWorked;
            return wSalary;
        }
    }
}

Here is an example of accessing the above value:

@{
    ViewBag.Title = "Payroll Preparation";
}

<p>Weekly Salary: @ViewBag.WeeklySalary</p>

A simple function is one that doesn't use any parameter but returns a value. To support it, the .NET Framework provides a Func<> delegate that uses the following syntax:

public delegate TResult Func<out TResult>()

The out TResult expression indicates that the delegate returns a value as TResult. When creating the method for the delegate, you must indicate the desired return value. To associate the method to the delegate, declare a Func<> variable. Between < and >, include the same return type as the method. Initialize the variable with the name of the method. You can then call the variable as if it were a method. This can be done as follows:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class SalaryEvaluationController : Controller
    {
        // GET: SalaryEvaluation
        public ActionResult Index()
        {
            Func<double> eval = new Func<double>(Calculate);

            ViewBag.WeeklySalary = eval().ToString("F");

            return View();
        }

        public double Calculate()
        {
            double hSalary = 25.75;
            double tWorked = 38.50;

            double wSalary = hSalary * tWorked;
            return wSalary;
        }
    }
}

In the above code, we used the new operator to initialize the variable. You can omit it. Here is an example:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class SalaryEvaluationController : Controller
    {
        // GET: SalaryEvaluation
        public ActionResult Index()
        {
            Func<double> eval = Calculate;

            ViewBag.WeeklySalary = eval().ToString("F");

            return View();
        }

        public double Calculate()
        {
            double hSalary = 25.75;
            double tWorked = 38.50;

            double wSalary = hSalary * tWorked;
            return wSalary;
        }

    }
}

A Simple Anonymous Function Delegate

You can use the delegate keyword to create an anonymous function delegate. The technique is the same we have used so far. Here is an example:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class SalaryEvaluationController : Controller
    {
        // GET: SalaryEvaluation
        public ActionResult Index()
        {
            Func<double> eval = delegate ()
            {
                double hSalary = 25.75;
                double tWorked = 38.50;

                double wSalary = hSalary * tWorked;
                return wSalary;
            };

            ViewBag.WeeklySalary = eval().ToString("F");

            return View();
        }
    }
}

A Simple Lambda Expression

A function delegate that uses a parameter supports lambda expressions. To implement it, remove the delegate keyword and add the => operator after the parentheses. Here is an example:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class SalaryEvaluationController : Controller
    {
        // GET: SalaryEvaluation
        public ActionResult Index()
        {
            Func<double> eval = () =>
            {
                double hSalary = 25.75;
                double tWorked = 38.50;

                double wSalary = hSalary * tWorked;
                return wSalary;
            };

            ViewBag.WeeklySalary = eval().ToString("F");

            return View();
        }
    }
}

A Function Delegate with a Parameter

To support function delegates that use one parameter, the .NET Framework provides a delegate that uses the following syntax:

public delegate TResult Func<in T, out TResult>(T arg);

This syntax is for a function that takes one argument (and of course returns a value). Here is an example of such a function (and how to access it):

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public delegate double Operation(double a);

    public class SalaryEvaluationController : Controller
    {
        private double hourlySalary = 12.75;

        // GET: SalaryEvaluation
        public ActionResult Index()
        {
            Operation oper = Multiply;

            double dailySalary = EvaluateSalary(oper);

            ViewBag.DailySalary = dailySalary.ToString("F");

            return View();
        }

        public double Multiply(double timeWorked)
        {
            if (timeWorked <= 8)
            {
                return hourlySalary * timeWorked;
            }
            else
            {
                double regularPay = 8.00 * hourlySalary;
                double overtimePay = (timeWorked - 8.00) * hourlySalary * 1.50;
                return regularPay + overtimePay;
            }
        }

        public double EvaluateSalary(Operation calc)
        {
            return calc(hourlySalary);
        }
    }
}

To simply your code, you can use a Func delegate. Instead of this:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public delegate double Operation(double a);

    public class SalaryEvaluationController : Controller
    {
        private double hourlySalary = 12.75;

        // GET: SalaryEvaluation
        public ActionResult Index()
        {
            double dailySalary = EvaluateSalary(timeWorked =>
            {
                if (timeWorked <= 8)
                {
                    return hourlySalary * timeWorked;
                }
                else
                {
                    double regularPay = 8.00 * hourlySalary;
                    double overtimePay = (timeWorked - 8.00) * hourlySalary * 1.50;
                    return regularPay + overtimePay;
                }
            });

            ViewBag.DailySalary = dailySalary.ToString("F");

            return View();
        }

        public double EvaluateSalary(Operation calc)
        {
            return calc(hourlySalary);
        }
    }
}

You can use this:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class SalaryEvaluationController : Controller
    {
        private double hourlySalary = 12.75;

        // GET: SalaryEvaluation
        public ActionResult Index()
        {
            Func<double, double> Calculate = new Func<double, double>(timeWorked =>
            {
                if (timeWorked <= 8)
                {
                    return hourlySalary * timeWorked;
                }
                else
                {
                    double regularPay = 8.00 * hourlySalary;
                    double overtimePay = (timeWorked - 8.00) * hourlySalary * 1.50;
                    return regularPay + overtimePay;
                }
            });

            double dailySalary = Calculate(12.00);

            ViewBag.DailySalary = dailySalary.ToString();

            return View();
        }
    }
}

Because the above function included many lines of code, we created a body for it and delimited it with curly brackets. If a function includes a single line of code, it doesn't need a body. Here is an example:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class SalaryEvaluationController : Controller
    {
        private double hourlySalary = 12.75;

        // GET: SalaryEvaluation
        public ActionResult Index()
        {
            Func<double, double> Calculate = timeWorked => hourlySalary * timeWorked;

            double dailySalary = Calculate(12.00);

            ViewBag.DailySalary = dailySalary.ToString();

            return View();
        }
    }
}

A Function Delegate as Type

Returning a Function Delegate

A function delegate is a type, like a value type or a class. As such, you can create a method that returns a function. To do this, specify Func<> as the return type. The parameter type can be a value type. Here is an example:

using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public Func<double> Calculate()
        {
        	. . .
        }
    }
}

Do whatever you want in the method but before it ends, return a value of type Func<>. Here is an example:

using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        public Func<int> Calculate()
        {
            Func<int> result = Addition;

            return result;
        }

        private int Addition()
        {
            Random rndNumber = new Random();
            int number1 = rndNumber.Next(0, 20);
            int number2 = rndNumber.Next(0, 20);
            int total = number1 + number2;

            return total;
        }
    }
}

You can also just return the name of the method that returns the function delegate. Here is an example:

using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        public Func<int> Calculate()
        {
            return Addition;
        }

        private int Addition()
        {
            Random rndNumber = new Random();
            int number1 = rndNumber.Next(0, 20);
            int number2 = rndNumber.Next(0, 20);
            int total = number1 + number2;

            return total;
        }
    }
}

When calling the method, you can assign it to a variable of type Func<>. Here is an example:

using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Func<int> eval = Calculate();

            eval();

            return View();
        }

        public Func&lt;int&gt; Calculate()
        {
            Func&lt;int&gt; result = Addition;

            return result;
        }

        private int Addition()
        {
            Random rndNumber = new Random();
            int number1 = rndNumber.Next(0, 20);
            int number2 = rndNumber.Next(0, 20);
            int total = number1 + number2;

            return total;
        }
    }
};

A Function Delegate as Parameter With One Parameter

We already know that you can pass a function as argument if you use a delegate. Here is an example:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public delegate double Operation(double a);

    public class SalaryEvaluationController : Controller
    {
        private double value = 148.86;

        public ActionResult Index()
        {
            double area = Calculate(Multiply);

            ViewBag.AreaOfCube = area;

            return View();
        }

        public double Multiply(double side)
        {
            return side * side;
        }

        public double Calculate(Operation oper)
        {
            return oper(value);
        }
    }
}

When creating the method, instead of your own function, you can use Func<>. Here is an example for a function that takes one argument:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class SalaryEvaluationController : Controller
    {
        private double value = 148.86;

        // GET: SalaryEvaluation
        public ActionResult Index()
        {
            double area = Calculate(Multiply);

            ViewBag.AreaOfCube = area;

            return View();
        }

        public double Multiply(double side)
        {
            return side * side;
        }

        public double Calculate(Func<double, double> oper)
        {
            return oper(value) * 6.00;
        }
    }
}

Calling a One-Parameter Function Locally

When calling the method, instead of first creating a method that would be passed as argument, you can define the method directly where it is needed. Here is an example:

using System;
using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class SalaryEvaluationController : Controller
    {
        private double value = 148.86;

        // GET: SalaryEvaluation
        public ActionResult Index()
        {
            double area = Calculate((double side) =>
            {
                return side * side;
            });

            ViewBag.AreaOfCube = area;

            return View();
        }
        

        public double Calculate(Func<double, double> oper)
        {
            return oper(value) * 6.00;
        }
    }
}

Remember that you can omit the data type(s) of the parameter(s). Also remember that if the method is using one parameter, the parameter doesn't need parentheses. And if the method contains a single statement, it doesn't need a body. Here is an example:

using System.Web.Mvc;

namespace Exercises.Controllers
{
    public class HomeController : Controller
    {
        private double value = 148.86;

        public ActionResult Index()
        {
            double area = Calculate(side => side * side);

            ViewBag.AreaOfCube = area;

            return View();
        }

        public double Calculate(Func<double, double> oper)
        {
            return oper(value);
        }
    }
}

Practical LearningPractical Learning: Calling a One-Paremeter Function Locally

  1. In the Solution Explorer, under Views, right-click Home -> Add -> View...
  2. Type CustomerOrderPreparation as the name of the view
  3. Click Add
  4. Change the code as follows:
    @{
        ViewBag.Title = "Customer Order Preparation";
    }
    
    <h2>Prepare Customer Order</h2>
    
    @{
        SchoolUniCorp1.Controllers.HomeController hc = new SchoolUniCorp1.Controllers.HomeController();
    
        int iQuantityShirts = int.Parse(Request["QuantityShirts"]);
        int iQuantityPants = int.Parse(Request["QuantityPants"]);
    
        double subTotalShirts = hc.SubTotalCalculation(q => q * 15.00, iQuantityShirts);
        double subTotalPants = hc.SubTotalCalculation(q => q * 20.00, iQuantityPants);
    }
    
    @using (Html.BeginForm())
    {
        <table>
            <tr>
                <td class="bottom-border caption-cell">&nbsp;</td>
                <td class="bottom-border bold">Unit Price</td>
                <td class="bottom-border control-cell bold">Quantity</td>
                <td class="bottom-border bold">Sub-Total</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts:</td>
                <td class="bottom-border">@Html.Label("UnitPriceShirts", "15.00", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirts", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalShirts", @subTotalShirts.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border control-cell bold">Pants:</td>
                <td class="bottom-border">@Html.Label("SubTotalPants", "20.00", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityPants", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("UnitPricePants", @subTotalPants.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
        </table>
    }
  5. Click the CustomerOrderStartUp.cs tab to activate it
  6. To execute the project, on the main menu, click Debug -> Start Without Debugging
  7. In the text boxes, type some small numbers such as
    Shirts: 3
    Pants:  2

    Calling a One-Paremeter Function Locally

  8. Click the Prepare Order button

    Calling a One-Paremeter Function Locally

  9. Close the browser and return to your programming environment

Processing a Function in its Method

When creating a method that will be used to access function delegate, you can involve that function in an operation with constants or external values of your choice. After doing this, when calling the method, you can just pass a pamater and not process it again.

Practical LearningPractical Learning: Processing a Function in its Method

  1. Click the HomeController.cs tab and change it as follows:
    using System.Web.Mvc;
    
    namespace SchoolUniCorp1.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult About()
            {
                ViewBag.Message = "Your application description page.";
    
                return View();
            }
    
            public ActionResult Contact()
            {
                ViewBag.Message = "Your contact page.";
    
                return View();
            }
    
            public ActionResult CustomerOrderStartUp()
            {
                return View();
            }
    
            public ActionResult CustomerOrderPreparation(string QuantityShirts, string QuantityPants)
            {
                return View();
            }
    
            public double EvaluateShirts(Func<int, double> calc, int qty)
            {
                return calc(qty) * 15.00;
            }
    
            public double EvaluatePants(Func<int, double> calc, int qty)
            {
                return calc(qty) * 20.00;
            }
        }
    }
  2. Click the CustomerOrderPreparation.cshtml tab and change it as follows:
    @{
        ViewBag.Title = "Customer Order Preparation";
    }
    
    <h2>Prepare Customer Order</h2>
    
    @{
        SchoolUniCorp1.Controllers.HomeController hc = new SchoolUniCorp1.Controllers.HomeController();
    
        int iQuantityShirts = int.Parse(Request["QuantityShirts"]);
        int iQuantityPants = int.Parse(Request["QuantityPants"]);
    
        double subTotalShirts = hc.EvaluateShirts(q => q, iQuantityShirts);
        double subTotalPants = hc.EvaluatePants(q => q, iQuantityPants);
    }
    
    @using (Html.BeginForm())
    {
        <table>
            <tr>
                <td class="bottom-border caption-cell">&nbsp;</td>
                <td class="bottom-border bold">Unit Price</td>
                <td class="bottom-border control-cell bold">Quantity</td>
                <td class="bottom-border bold">Sub-Total</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts:</td>
                <td class="bottom-border">@Html.Label("UnitPriceShirts", "15.00", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirts", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalShirts", @subTotalShirts.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border control-cell bold">Pants:</td>
                <td class="bottom-border">@Html.Label("SubTotalPants", "20.00", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityPants", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("UnitPricePants", @subTotalPants.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
        </table>
    }
  3. Click the CustomerOrderStartUp.cs tab to activate it
  4. To execute the project, on the main menu, click Debug -> Start Without Debugging
  5. In the text boxes, type some small numbers such as
    Shirts: 2
    Pants:  4
  6. Click the Prepare Order button
  7. Close the browser and return to your programming environment

Applying Value Processing to a Function Delegate

Obviously it is not always enough to just call a function delegate and pass an argument to it. Many times, you want the function delegate to perform some operations on its argument(s) and produce a result as complex as you want. One way you can do this is to include one or more conditional statements in the method. In fact, you can even call other methods or involve other libraries in the method that calls the function delegate.

Practical LearningPractical Learning: Applying Value Processing to a Function Delegate

  1. Click the HomeController.cs tab and change it as follows:
    using System.Web.Mvc;
    
    namespace SchoolUniCorp1.Controllers
    {
        public class HomeController : Controller
        {
            . . . No Change
    
            public ActionResult CustomerOrderStartUp()
            {
                return View();
            }
    
            public ActionResult CustomerOrderPreparation(string QuantityShirts, string QuantityPants)
            {
                return View();
            }
    
            public double EvaluateShirts(Func<int, double> calc, int qty)
            {
                return calc(qty) * 15.00;
            }
    
            public double EvaluatePants(Func<int, double> calc, int qty)
            {
                return calc(qty) * 20.00;
            }
    
            public double EvaluateShipping(Func<double, double> calc, double amt)
            {
                double rate = 0.00;
    
                if (amt > 125.00)
                    rate = 14.95;
                else if (amt > 75.00)
                    rate = 10.95;
                else if (amt > 25.00)
                    rate = 8.95;
                else
                    rate = 6.50;
    
                return calc(rate);
            }
        }
    }
  2. Click the CustomerOrderOperation.cshtml tab and change the document as follows:
    @{
        ViewBag.Title = "Customer Order Preparation";
    }
    
    <h2>Prepare Customer Order</h2>
    
    @{
        SchoolUniCorp1.Controllers.HomeController hc = new SchoolUniCorp1.Controllers.HomeController();
    
        int iQuantityShirts = int.Parse(Request["QuantityShirts"]);
        int iQuantityPants = int.Parse(Request["QuantityPants"]);
    
        double subTotalShirts = hc.EvaluateShirts(q => q, iQuantityShirts);
        double subTotalPants = hc.EvaluatePants(q => q, iQuantityPants);
        double shippingAndHanling = hc.EvaluateShipping(s => s, subTotalShirts + subTotalPants);
    }
    
    @using (Html.BeginForm())
    {
        <table>
            <tr>
                <td class="bottom-border caption-cell">&nbsp;</td>
                <td class="bottom-border bold">Unit Price</td>
                <td class="bottom-border control-cell bold">Quantity</td>
                <td class="bottom-border bold">Sub-Total</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts:</td>
                <td class="bottom-border">@Html.Label("UnitPriceShirts", "15.00", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirts", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalShirts", @subTotalShirts.ToString("F"), new { style = "width: 70px" })</td>
            </tr>
            <tr>
                <td class="lowest-border control-cell bold">Pants:</td>
                <td class="lowest-border">@Html.Label("SubTotalPants", "20.00", new { style = "width: 80px" })</td>
                <td class="lowest-border">@Html.TextBox("QuantityPants", "0", new { style = "width: 60px" })</td>
                <td class="lowest-border">@Html.Label("UnitPricePants", @subTotalPants.ToString("F"), new { style = "width: 70px" })</td>
            </tr>
        </table>
        <table>
            <tr>
                <td class="lowest-border caption-cell">&nbsp;</td>
                <td style="width: 180px; border-bottom: 3px solid black;"><b>Shipping &amp; Handling</b></td>
                <td class="lowest-border">@Html.Label("ShippingAndHanling", @shippingAndHanling.ToString("F"), new { style = "width: 70px" })</td>
            </tr>
        </table>
    }
  3. Click the CustomerOrderStartUp.cs tab to activate it
  4. To execute the project, on the main menu, click Debug -> Start Without Debugging
  5. In the Pants text box, type a small number such as 1

    Calling a One-Paremeter Function Locally

  6. Click the Prepare Customer Order button

    Calling a One-Paremeter Function Locally

  7. Close the browser and return to your programming environment

A Function Delegate with Two Parameters

Depending on your project, you may need a function that uses two parameters. To support this concept for function delegates, the .NET Framework provides the following version of the Func<> delegate:

public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);

This generic delegate uses three parameter types. The last parameter type,TResult, is the return type of the function. The first two types represent the data types of the parameters. In a simple version, they can be value types (number, character, Boolean) or a string. They can be the same or different types.

As seen with function delegates of one parameter, you can create a method that takes one parameter, you can create a method that takes a function of two parameters and, in the method, simply call the function and pass two arguments. you can use arguments you also pass to the method. Here is an example:

public double EvaluateSubTotal(Func<int, double, double> calc, int qty, double amount)
{
    return calc(qty, amount);
}

In this case, when calling the method, in the placeholder of the function passed as parameter, type parentheses and in which you must include two arguments separated by a comma. Outside the parentheses, type => followed by the desired operation for the arguments. Here is an example:

double subTotalShirtsSmall = hc.EvaluateSubTotal((q, a) => q * a,
												 iQuantityShirtsSmall, dUnitPriceShirtsSmall);

Alternatively, you can perform the operation in the method that uses the function delegate. Here is an example:

public double EvaluateSubTotal(Func<int, double, double> calc, int qty, double amount)
{
    return qty * amount;
}

Alternatively, you can define a function delegate where it is needed, then call it. Here is an example

@{
    double subTotal = 2425.75;
    int shippingAndHanling = 36.75;

    Func<double, double, double> Plus = (a, b) => a + b;

    double invoiceTotal = Plus(subTotal, shippingAndHanling);
}

Practical LearningPractical Learning: Using a Function Delegate with Two Parameters

  1. Click the HomeController.cshtml tab to access it and change the CustomerOrderPreparation() method and create a new method as follows:
    using System.Web.Mvc;
    
    namespace SchoolUniCorp1.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult About()
            {
                ViewBag.Message = "Your application description page.";
    
                return View();
            }
    
            public ActionResult Contact()
            {
                ViewBag.Message = "Your contact page.";
    
                return View();
            }
    
            public ActionResult CustomerOrderStartUp()
            {
                return View();
            }
    
            public ActionResult CustomerOrderPreparation(string QuantityShirtsSmall, string QuantityShirtsMedium, string QuantityShirtsLarge,
                                                         string UnitPriceShirtsSmall, string UnitPriceShirtsMedium, string UnitPriceShirtsLarge,
                                                         string QuantityPantsSmall, string QuantityPantsMedium, string QuantityPantsLarge,
                                                         string UnitPricePantsSmall, string UnitPricePantsMedium, string UnitPricePantsLarge)
            {
                return View();
            }
    
            public double EvaluateSubTotal(Func<int, double, double> calc, int qty, double amount)
            {
                return calc(qty, amount);
            }
    
            public double EvaluateShipping(Func<double, double> calc, double amt)
            {
                double rate = 0.00;
    
                if (amt > 125.00)
                    rate = 14.95;
                else if (amt > 75.00)
                    rate = 10.95;
                else if (amt > 25.00)
                    rate = 8.95;
                else
                    rate = 6.50;
    
                return calc(rate);
            }
        }
    }
  2. Click the CustomerOrderPreparation.cshtml tab and change its document as follows:
    @{
        ViewBag.Title = "Customer Order Preparation";
    }
    
    <h2>Prepare Customer Order</h2>
    
    @{
        SchoolUniCorp1.Controllers.HomeController hc = new SchoolUniCorp1.Controllers.HomeController();
    
        int iQuantityShirtsSmall = int.Parse(Request["QuantityShirtsSmall"]);
        int iQuantityShirtsMedium = int.Parse(Request["QuantityShirtsMedium"]);
        int iQuantityShirtsLarge = int.Parse(Request["QuantityShirtsLarge"]);
        int iQuantityPantsSmall = int.Parse(Request["QuantityPantsSmall"]);
        int iQuantityPantsMedium = int.Parse(Request["QuantityPantsMedium"]);
        int iQuantityPantsLarge = int.Parse(Request["QuantityPantsLarge"]);
    
        double dUnitPriceShirtsSmall  = double.Parse(Request["UnitPriceShirtsSmall"]);
        double dUnitPriceShirtsMedium = double.Parse(Request["UnitPriceShirtsMedium"]);
        double dUnitPriceShirtsLarge = double.Parse(Request["UnitPriceShirtsLarge"]);
        double dUnitPricePantsSmall = double.Parse(Request["UnitPricePantsSmall"]);
        double dUnitPricePantsMedium = double.Parse(Request["UnitPricePantsMedium"]);
        double dUnitPricePantsLarge = double.Parse(Request["UnitPricePantsLarge"]);
    
        double subTotalShirtsSmall = hc.EvaluateSubTotal((q, a) => q * a, iQuantityShirtsSmall, dUnitPriceShirtsSmall);
        double subTotalShirtsMedium = hc.EvaluateSubTotal((q, a) => q * a, iQuantityShirtsMedium, dUnitPriceShirtsMedium);
        double subTotalShirtsLarge = hc.EvaluateSubTotal((q, a) => q * a, iQuantityShirtsLarge, dUnitPriceShirtsLarge);
        double subTotalPantsSmall = hc.EvaluateSubTotal((q, a) => q * a, iQuantityPantsSmall, dUnitPricePantsSmall);
        double subTotalPantsMedium = hc.EvaluateSubTotal((q, a) => q * a, iQuantityPantsMedium, dUnitPricePantsMedium);
        double subTotalPantsLarge = hc.EvaluateSubTotal((q, a) => q * a, iQuantityPantsLarge, dUnitPricePantsLarge);
    
        double shippingAndHanling = 0.00;
    }
    
    @using (Html.BeginForm())
    {
        <table>
            <tr>
                <td class="bottom-border caption-cell">&nbsp;</td>
                <td class="bottom-border bold">Unit Price</td>
                <td class="bottom-border control-cell bold">Quantity</td>
                <td class="bottom-border bold">Sub-Total</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts Small:</td>
                <td class="bottom-border">@Html.TextBox("UnitPriceShirtsSmall", "UnitPriceShirtsSmall", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirtsSmall", "QuantityShirtsSmall", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalShirtsSmall", @subTotalShirtsSmall.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts Medium:</td>
                <td class="bottom-border">@Html.TextBox("UnitPriceShirtsMedium", @"UnitPriceShirtsMedium", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirtsMedium", @"QuantityShirtsMedium", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalShirtsMedium", @subTotalShirtsMedium.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts Large:</td>
                <td class="bottom-border">@Html.TextBox("UnitPriceShirtsLarge", @"UnitPriceShirtsLarge", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirtsLarge", @"QuantityShirtsLarge", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalShirtsLarge", @subTotalShirtsLarge.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Pants Small:</td>
                <td class="bottom-border">@Html.TextBox("UnitPricePantsSmall", @"UnitPricePantsSmall", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityPantsSmall", @"QuantityPantsSmall", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalPantsSmall", @subTotalPantsSmall.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Pants Medium:</td>
                <td class="bottom-border">@Html.TextBox("UnitPricePantsMedium", @"UnitPricePantsMedium", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityPantsMedium", @"QuantityPantsMedium", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalPantsMedium", @subTotalPantsMedium.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="lowest-border bold">Pants Large:</td>
                <td class="lowest-border">@Html.TextBox("UnitPricePantsLarge", @"UnitPricePantsLarge", new { style = "width: 80px" })</td>
                <td class="lowest-border">@Html.TextBox("QuantityPantsLarge", @"QuantityPantsLarge", new { style = "width: 60px" })</td>
                <td class="lowest-border">@Html.Label("SubTotalPantsLarge", @subTotalPantsLarge.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
        </table>
        <table>
            <tr>
                <td class="lowest-border caption-cell">&nbsp;</td>
                <td style="width: 180px; border-bottom: 3px solid black;"><b>Shipping &amp; Handling</b></td>
                <td class="lowest-border">@Html.Label("ShippingAndHanling", @shippingAndHanling.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
        </table>
    }
  3. Access the CustomerOrderStartUp.cshtml tab and change its document as follows:
    @{
        ViewBag.Title = "Customer Order Start-Up";
    }
    
    <h2>Customer Order Start-Up</h2>
    
    @using (Html.BeginForm("CustomerOrderPreparation", "Home", FormMethod.Post))
    {
        <table>
            <tr>
                <td class="bottom-border caption-cell">&nbsp;</td>
                <td class="bottom-border control-cell bold">Quantity</td>
                <td class="bottom-border bold">Unit Price</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts Small:</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirtsSmall", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.TextBox("UnitPriceShirtsSmall", "15.25", new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts Medium:</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirtsMedium", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.TextBox("UnitPriceShirtsMedium", "16.70", new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts Large:</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirtsLarge", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.TextBox("UnitPriceShirtsLarge", "18.50", new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border control-cell bold">Pants Small:</td>
                <td class="bottom-border">@Html.TextBox("QuantityPantsSmall", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.TextBox("UnitPricePantsSmall", "18.35", new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border control-cell bold">Pants Medium:</td>
                <td class="bottom-border">@Html.TextBox("QuantityPantsMedium", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.TextBox("UnitPricePantsMedium", "21.50", new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border control-cell bold">Pants Large:</td>
                <td class="bottom-border">@Html.TextBox("QuantityPantsLarge", "0", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.TextBox("UnitPricePantsLarge", "24.25", new { style = "width: 80px" })</td>
            </tr>
        </table>
        <hr />
        <table>
            <tr>
                <td class="caption-cell">&nbsp;</td>
                <td><input type="submit" name="btnPrepareCustomerOrder" value="Prepare Customer Order" /></td>
            </tr>
        </table>
    }
  4. To execute the project, on the main menu, click Debug -> Start Without Debugging
  5. In the text boxes, type some small numbers such as

    Quantity
    Shirts Small 3
    Shirts Medium 1
    Shirts Large 4
    Pants Small 2
    Pants Medium 3
    Pants Large 5

    Calling a One-Paremeter Function Locally

  6. Click the Prepare Customer Order button

    Calling a One-Paremeter Function Locally

  7. Close the forms and return to your programming environment

A .NET Function Delegate With Many Parameters

To support function delegates that can use various numbers and types of parameters, the .NET Framework provides 17 versions of the Func delegates. One version is for a function that uses no parameter. The other versions are for functions that take 1 to 16 arguments. The syntaxes of the function delegates are:

public delegate TResult Func<out TResult>();
public delegate TResult Func<in T, out TResult>(T arg);
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(	T1 arg1, T2 arg2, T3 arg3, T4 arg4);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, out TResult>(	T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11,  T12 arg12);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);

As we saw already, for the first syntax, TResult is the only factor and it represents the return value. For the other syntaxes, the last parameter, TResult, is the return value. This means that, when declaring the Func<> variable, between < and >, start with the type(s) of the parameter(s) and end with the return type.

Everyone of these functions can be passed as argument or returned from a method.

Practical LearningPractical Learning: Using a Funtion Delegate of Many Parameters

  1. Access the HomeController.cs file and change it as follows:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace SchoolUniCorp1.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult About()
            {
                ViewBag.Message = "Your application description page.";
    
                return View();
            }
    
            public ActionResult Contact()
            {
                ViewBag.Message = "Your contact page.";
    
                return View();
            }
    
            public ActionResult CustomerOrderStartUp()
            {
                return View();
            }
    
            public ActionResult CustomerOrderPreparation(string QuantityShirtsSmall, string QuantityShirtsMedium, string QuantityShirtsLarge,
                                                         string UnitPriceShirtsSmall, string UnitPriceShirtsMedium, string UnitPriceShirtsLarge,
                                                         string QuantityPantsSmall, string QuantityPantsMedium, string QuantityPantsLarge,
                                                         string UnitPricePantsSmall, string UnitPricePantsMedium, string UnitPricePantsLarge)
            {
                return View();
            }
    
            public double EvaluateSubTotal(Func<int, double, double> calc, int qty, double amount)
            {
                return calc(qty, amount);
            }
    
            public int SextupleAddition(Func<int, int, int, int, int, int, int> calc, int sub1, int sub2, int sub3, int sub4, int sub5, int sub6)
            {
                return calc(sub1, sub2, sub3, sub4, sub5, sub6);
            }
    
            public double SextupleAddition(Func<double, double, double, double, double, double, double> calc, double sub1, double sub2, double sub3, double sub4, double sub5, double sub6)
            {
                return calc(sub1, sub2, sub3, sub4, sub5, sub6);
            }
    
            public double EvaluateShipping(Func<double, double> calc, double amt)
            {
                double rate = 0.00;
    
                if (amt > 125.00)
                    rate = 14.95;
                else if (amt > 75.00)
                    rate = 10.95;
                else if (amt > 25.00)
                    rate = 8.95;
                else
                    rate = 6.50;
    
                return calc(rate);
            }
        }
    }
  2. Access the CustomerOrderPreparation.cshtml file and change it as follows:
    @{
        ViewBag.Title = "Customer Order Preparation";
    }
    
    <h2>Prepare Customer Order</h2>
    
    @{
        SchoolUniCorp1.Controllers.HomeController hc = new SchoolUniCorp1.Controllers.HomeController();
    
        int iQuantityShirtsSmall = int.Parse(Request["QuantityShirtsSmall"]);
        int iQuantityShirtsMedium = int.Parse(Request["QuantityShirtsMedium"]);
        int iQuantityShirtsLarge = int.Parse(Request["QuantityShirtsLarge"]);
        int iQuantityPantsSmall = int.Parse(Request["QuantityPantsSmall"]);
        int iQuantityPantsMedium = int.Parse(Request["QuantityPantsMedium"]);
        int iQuantityPantsLarge = int.Parse(Request["QuantityPantsLarge"]);
    
        double dUnitPriceShirtsSmall  = double.Parse(Request["UnitPriceShirtsSmall"]);
        double dUnitPriceShirtsMedium = double.Parse(Request["UnitPriceShirtsMedium"]);
        double dUnitPriceShirtsLarge = double.Parse(Request["UnitPriceShirtsLarge"]);
        double dUnitPricePantsSmall = double.Parse(Request["UnitPricePantsSmall"]);
        double dUnitPricePantsMedium = double.Parse(Request["UnitPricePantsMedium"]);
        double dUnitPricePantsLarge = double.Parse(Request["UnitPricePantsLarge"]);
    
        double subTotalShirtsSmall = hc.EvaluateSubTotal((q, a) => q * a, iQuantityShirtsSmall, dUnitPriceShirtsSmall);
        double subTotalShirtsMedium = hc.EvaluateSubTotal((q, a) => q * a, iQuantityShirtsMedium, dUnitPriceShirtsMedium);
        double subTotalShirtsLarge = hc.EvaluateSubTotal((q, a) => q * a, iQuantityShirtsLarge, dUnitPriceShirtsLarge);
        double subTotalPantsSmall = hc.EvaluateSubTotal((q, a) => q * a, iQuantityPantsSmall, dUnitPricePantsSmall);
        double subTotalPantsMedium = hc.EvaluateSubTotal((q, a) => q * a, iQuantityPantsMedium, dUnitPricePantsMedium);
        double subTotalPantsLarge = hc.EvaluateSubTotal((q, a) => q * a, iQuantityPantsLarge, dUnitPricePantsLarge);
    
        int quantities = hc.SextupleAddition((a, b, c, d, e, f) => a + b + c + d + e + f, iQuantityShirtsSmall, iQuantityShirtsMedium, iQuantityShirtsLarge, iQuantityPantsSmall, iQuantityPantsMedium, iQuantityPantsLarge);
        double subTotal = hc.SextupleAddition((a, b, c, d, e, f) => a + b + c + d + e + f, subTotalShirtsSmall, subTotalShirtsMedium, subTotalShirtsLarge, subTotalPantsSmall, subTotalPantsMedium, subTotalPantsLarge);
    
        Func<double, double, double> Plus = (a, b) => a + b;
    
        double shippingAndHanling = hc.EvaluateShipping(x => x, subTotal);
        double invoiceTotal = Plus(subTotal, shippingAndHanling);
    }
    
    @using (Html.BeginForm())
    {
        <table style="width: 400px">
            <tr>
                <td class="bottom-border caption-cell">&nbsp;</td>
                <td class="bottom-border bold">Unit Price</td>
                <td class="bottom-border control-cell bold">Quantity</td>
                <td class="bottom-border bold">Sub-Total</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts Small:</td>
                <td class="bottom-border">@Html.TextBox("UnitPriceShirtsSmall", "UnitPriceShirtsSmall", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirtsSmall", "QuantityShirtsSmall", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalShirtsSmall", @subTotalShirtsSmall.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts Medium:</td>
                <td class="bottom-border">@Html.TextBox("UnitPriceShirtsMedium", @"UnitPriceShirtsMedium", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirtsMedium", @"QuantityShirtsMedium", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalShirtsMedium", @subTotalShirtsMedium.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Shirts Large:</td>
                <td class="bottom-border">@Html.TextBox("UnitPriceShirtsLarge", @"UnitPriceShirtsLarge", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityShirtsLarge", @"QuantityShirtsLarge", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalShirtsLarge", @subTotalShirtsLarge.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Pants Small:</td>
                <td class="bottom-border">@Html.TextBox("UnitPricePantsSmall", @"UnitPricePantsSmall", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityPantsSmall", @"QuantityPantsSmall", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalPantsSmall", @subTotalPantsSmall.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="bottom-border bold">Pants Medium:</td>
                <td class="bottom-border">@Html.TextBox("UnitPricePantsMedium", @"UnitPricePantsMedium", new { style = "width: 80px" })</td>
                <td class="bottom-border">@Html.TextBox("QuantityPantsMedium", @"QuantityPantsMedium", new { style = "width: 60px" })</td>
                <td class="bottom-border">@Html.Label("SubTotalPantsMedium", @subTotalPantsMedium.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="lowest-border"><b>Pants Large:</b></td>
                <td class="lowest-border">@Html.TextBox("UnitPricePantsLarge", @"UnitPricePantsLarge", new { style = "width: 80px" })</td>
                <td class="lowest-border">@Html.TextBox("QuantityPantsLarge", @"QuantityPantsLarge", new { style = "width: 60px" })</td>
                <td class="lowest-border">@Html.Label("SubTotalPantsLarge", @subTotalPantsLarge.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
        </table>
        <table style="width: 400px">
            <tr>
                <td style="width: 250px; border-bottom: 3px solid black;">&nbsp;</td>
                <td style="width: 180px; border-bottom: 3px solid black;"><b>Sub-Total:</b></td>
                <td class="lowest-border caption-cell">@Html.Label("Quantities", @quantities.ToString("F"), new { style = "width: 70px" })</td>
                <td class="lowest-border">@Html.Label("SubTotal", @subTotal.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
        </table>
        <table>
            <tr>
                <td class="bottom-border caption-cell">&nbsp;</td>
                <td style="width: 180px; border-bottom: 1px solid black;"><b>Shipping &amp; Handling</b></td>
                <td class="bottom-border">@Html.Label("ShippingAndHanling", @shippingAndHanling.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
            <tr>
                <td class="lowest-border">&nbsp;</td>
                <td style="width: 180px; border-bottom: 3px solid black;"><b>Invoice Total:</b></td>
                <td class="lowest-border">@Html.Label("InvoiceTotal", @invoiceTotal.ToString("F"), new { style = "width: 80px" })</td>
            </tr>
        </table>
    }
  3. Click the CustomerOrderStartUp.cshtml tab to activate its file and, to execute, on the main menu, click Debug -> Start Without Debugging
  4. In the text boxes, type some small numbers such as

    Quantity Unit Price
    Shirts Small 4 16.50
    Shirts Medium 2 18.25
    Shirts Large 2 20.50
    Pants Small 1  
    Pants Medium 0  
    Pants Large 4 22.75

    Calling a One-Paremeter Function Locally

  5. Click the Prepare Customer Order button

    Calling a One-Paremeter Function Locally

  6. Close the forms and return to your programming environment
  7. Close your programming environment

Previous Copyright © 2008-2019, FunctionX Next