Topics on Delegates
Topics on Delegates
A Delegate as a Function
Introduction
In many programming languages, such as Visual Basic or Pascal, a function is an action that formally produces a value. We say that a function returns a value. In the same way, you can create a delegate that returns a value.
The basic formula used to create a delegate that returns a value is:
[attributes] [modifier(s)] delegate return-type Name ([formal-parameters]);
When creating the delegate, specify the data type to the left side of the name of the delegate. Here is an example:
delegate double Evaluation();
When defining a function that would be associated with the delegate, the function must return the same type of value. Here is an example:
using System.Windows.Forms; namespace Exercises { delegate double Evaluation(); public partial class Exercise : Form { public Exercise() { InitializeComponent(); } public double Calculate() { return 0.00; } } }
Using a Function Delegate
To use the function, you can first declare a variable of the type of the delegate and initialize it using the new operator as doen for a class with 0 or a default constructor. In the parentheses, pass the name of the function. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation();
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
double Calculate()
{
return 0.00;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = new Evaluation(Calculate);
}
}
}
To use the delegate, you can call the variable as if it were a function. If you need the value returned by the delegate, declare another variable and initialize with a call to the delegate variable. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation();
public partial class Exercise : Form
{
public Exercise() => InitializeComponent();
double Calculate()
{
return 0.00;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = new Evaluation(Calculate);
double weeklySalary = eval();
}
}
}
You can then use the returned value as you see fit. For example, you can present it to the user. This can be done as follows:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation();
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
double Calculate()
{
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
double wSalary = hSalary * tWorked;
return wSalary;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = new Evaluation(Calculate);
double wage = eval();
txtNetPay.Text = wage.ToString("F");
}
}
}
In the above code, we first declared a variable to store the returned value of the delegate. This can be useful if you are planning to use the value many times. If you are planning to use the value only once, you can call the delegate directly where the value is needed. Here an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation();
public partial class Exercise : Form
{
public Exercise() => InitializeComponent();
double Calculate()
{
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
return hSalary * tWorked;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = new Evaluation(Calculate);
txtNetPay.Text = eval().ToString("F");
}
}
}
In the above example, we declared a variable for the delegate and initialized it as done for the variable of a class. This can be necessary if you are planning to use the delegate variable many times. If not, you can apply the initialization directly where the function delegate is called. Based on the previous two examples, this can be done as follows:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation();
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
double Calculate()
{
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
return hSalary * tWorked;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
double wage = new Evaluation(Calculate)();
txtNetPay.Text = wage.ToString("F");
}
}
}
Or as follows:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation();
public partial class Exercise : Form
{
public Exercise() => InitializeComponent();
double Calculate()
{
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
return hSalary * tWorked;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
txtNetPay.Text = new Evaluation(Calculate)().ToString("F");
}
}
}
We saw that, to initializing the delegate variable, we used the new operator, as follows:
Evaluation eval = new Evaluation(Calculate);
As an alternative, you can assign the name of the function to the delegate variable. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation();
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
double Calculate()
{
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
return hSalary * tWorked;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = Calculate;
txtNetPay.Text = eval().ToString("F");
}
}
}
A Function Delegate with a Parameter
A delegate that returns a value can also use one or more parameters. Here is an example of creating such a delegate:
delegate double Operation(double nbr);
Once again, you must have a function to associate to the delegate. When creating the function, it must have the same syntax as the delegate. In the body of the function, use or ignore the parameter. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation(double x);
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
double Calculate(double sal)
{
return 0.00;
}
}
}
Once again, before using the delegate, you can declare a variable and initialize it with the function. Here are two examples of doing it:
Operation oper = new Operation(Calculate);
Operation eval = Calculate;
When calling the delegate variable, you can declare a variable that is the type of the return value of the delegate. Call the delegate variable as if it were a function. In its parentheses, pass the appropriate number and type(s) of argument(s). Here is an example:
using System.Windows.Forms; namespace Exercises { delegate double Evaluation(double x); public partial class Exercise : Form { public Exercise() { InitializeComponent(); } double Calculate(double sal) {
double tWorked = double.Parse(txtTimeWorked.Text); return sal * tWorked; } private void btnCalculate_Click(object sender, System.EventArgs e) { double hSalary = double.Parse(txtHourlySalary.Text); Evaluation eval = new Evaluation(Calculate); double wage = eval(hSalary); txtNetPay.Text = wage.ToString("F"); } } }
Remember that, if you will use the delegate only one, you don't have to declare a variable for the delegate. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation(double x);
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
double Calculate(double sal)
{
return sal * 40.00;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
double hSalary = double.Parse(txtHourlySalary.Text);
double wage = new Evaluation(Calculate)(hSalary);
txtNetPay.Text = wage.ToString("F");
}
}
}
In the same way, you may not need a variable to store the value returned by the function delegate. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation(double x);
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
double Calculate(double sal)
{
return sal * 40.00;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
double hSalary = double.Parse(txtHourlySalary.Text);
txtNetPay.Text = new Evaluation(Calculate)(hSalary).ToString("F");
}
}
}
While we are on the subject of writing brief code, the follow code works as well:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation(double x);
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
double Calculate(double sal)
{
return sal * 40.00;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
txtNetPay.Text = new Evaluation(Calculate)(double.Parse(txtHourlySalary.Text)).ToString("F");
}
}
}
A Function Delegate with Many Parameters
A delegate that returns a value can use many parameters. The parameters can be of the same or different types. The associated function must use the same number and type(s) of parameters. Here is an example:
using System.Windows.Forms; namespace Exercises { delegate double Evaluation(double x, double y); public partial class Exercise : Form { public Exercise() { InitializeComponent(); } double Calculate(double sal, double time) { return sal * 40.00; } private void btnCalculate_Click(object sender, System.EventArgs e) { Evaluation eval = new Evaluation(Calculate); double hSalary = double.Parse(txtHourlySalary.Text); double tWorked = double.Parse(txtTimeWorked.Text); double wage = eval(hSalary, tWorked); txtNetPay.Text = wage.ToString("F"); } } }
Once again, you assign the name of the function to the delegate variable. Here is an example:
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = Calculate;
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
double wage = eval(hSalary, tWorked);
txtNetPay.Text = wage.ToString("F");
}
In fact, you may not need a variable for the delegate:
private void btnCalculate_Click(object sender, System.EventArgs e)
{
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
double wage = new Evaluation(Calculate)(hSalary, tWorked);
txtNetPay.Text = wage.ToString("F");
}
Here is a briefe version of the above code:
private void btnCalculate_Click(object sender, System.EventArgs e)
{
double wage = new Evaluation(Calculate)(double.Parse(txtHourlySalary.Text),
double.Parse(txtTimeWorked.Text));
txtNetPay.Text = wage.ToString("F");
}
In the same way, you may not need a variable to store the value returned by the delegate function, like this:
private void btnCalculate_Click(object sender, System.EventArgs e)
{
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
txtNetPay.Text = (new Evaluation(Calculate)(hSalary, tWorked)).ToString("F");
}
Or like this:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation(double x, double y);
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
double Calculate(double sal, double time)
{
return sal * time;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
txtNetPay.Text = (new Evaluation(Calculate)(double.Parse(txtHourlySalary.Text),
double.Parse(txtTimeWorked.Text))).ToString("F");
}
}
}
Function Delegates and Anonymous functions
Introduction
Earlier, we learned to create a simple delegate that returns a value and takes no argument. You may already know that you can nest a function in another. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation();
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = new Evaluation(Calculate);
double number = eval();
txtNetPay.Text = number.ToString("F");
double Calculate()
{
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
return hSalary * tWorked;
}
}
}
}
Function delegates support anonymous functions. In this case, when declaring a variable for the delegate, replace the combination of the new operator and the name of the delegate by the delegate keyword. Leave the parentheses empty and define the behavior you want, inside the curly brackets. This can be done as follows:
Evaluation eval = delegate() { double hSalary = double.Parse(txtHourlySalary.Text); double tWorked = double.Parse(txtTimeWorked.Text); return hSalary * tWorked; };
After doing this, you can just call the variable as done for a function, but if you want to get or use the returned value of the mehod, assign the call to another variable. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation();
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = delegate()
{
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
return hSalary * tWorked;
};
double number = eval();
txtNetPay.Text = number.ToString("F");
}
}
}
Using a Lambda Expression
Instead of first creating a formal function, you can use a local lambda expression. To do this, from the above code, simply omit the delegate keyword. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation();
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = () =>
{
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
return hSalary * tWorked;
};
double number = eval();
txtNetPay.Text = number.ToString("F");
}
}
}
An Anonymous Function Delegate with a Parameter
To create an anonymous delegate that uses a parameter, declare a variable for the delegate and initialize it with the delegate keyword and parentheses. In the parentheses of delegate(), provide a name for the parameter and its data type. When calling the delegate variable, pass an appropriate argument. Here is an example:
using System.Windows.Forms; namespace Exercises { delegate double Evaluation(double x); public partial class Exercise : Form { public Exercise() { InitializeComponent(); } private void btnCalculate_Click(object sender, System.EventArgs e) { Evaluation eval = delegate(double sal) { return sal * 40.00; }; double hSalary = double.Parse(txtHourlySalary.Text); double wage = eval(hSalary); txtNetPay.Text = wage.ToString("F"); } } }
As an alternative, you can omit the delegate keyword but add the => operator after the parentheses. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation(double x);
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = (sal) =>
{
return sal * 40.00;
};
double hSalary = double.Parse(txtHourlySalary.Text);
double wage = eval(hSalary);
txtNetPay.Text = wage.ToString("F");
}
}
}
An Anonymous Function Delegate with Parameters
Remember that a delegate can use more than one parameter. In fact, you can create its function in the body of the function that will call the delegate. Here is an example:
using System.Windows.Forms; namespace Exercises { delegate double Evaluation(double x, double y); public partial class Exercise : Form { public Exercise() { InitializeComponent(); } private void btnCalculate_Click(object sender, System.EventArgs e) { Evaluation eval = new Evaluation(Calculate); double hSalary = double.Parse(txtHourlySalary.Text); double tWorked = double.Parse(txtTimeWorked.Text); double wage = eval(hSalary, tWorked); txtNetPay.Text = wage.ToString("F"); double Calculate(double sal, double time) { return sal * time; } } } }
When creating the anonymous delegate, declare a variable for the delegate. Initialize it with delegate(). In the parentheses, pass the same number of parameters. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation(double x, double y);
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = delegate(double sal, double time)
{
return sal * time;
};
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
double wage = eval(hSalary, tWorked);
txtNetPay.Text = wage.ToString("F");
}
}
}
You can omit the delegate keyword, in which case you must add the => operator after the parentheses. Here is an example that uses one parameter:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation(double x, double y);
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = (double sal, double time) =>
{
return sal * time;
};
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
double wage = eval(hSalary, tWorked);
txtNetPay.Text = wage.ToString("F");
}
}
}
In the case you are not using the delegate keyword, you can omit the data type(s) of the parameter(s). Here is an example that uses one parameter:
using System.Windows.Forms;
namespace Exercises
{
delegate double Evaluation(double x, double y);
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Evaluation eval = (sal, time) =>
{
return sal * time;
};
double hSalary = double.Parse(txtHourlySalary.Text);
double tWorked = double.Parse(txtTimeWorked.Text);
double wage = eval(hSalary, tWorked);
txtNetPay.Text = wage.ToString("F");
}
}
}
A Delegate as Type
Returning a Delegate from a function
A delegate is a type. As such, it can be used as a type returned from a function. The delegate can be a void type. Therefore, create the delegate and create a function that uses the same syntax as the delegate. Here is an example:
using System; using System.Windows.Forms; namespace Exercises { delegate void Observation(); public partial class Form1 : Form { public Form1() { InitializeComponent(); } void Create() { } } }
Then create a function whose return type is the name of the delegate. The function must return a value that is the type of the delegate. Otherwise, you can return null. Here is an example:
using System;
using System.Windows.Forms;
namespace Exercises
{
delegate void Observation();
public partial class Form1 : Form
{
public Form1() => InitializeComponent();
void Create()
{
}
Observation Produce()
{
return null;
}
}
}
In the body of the function, you can declare a variable of the type of the delegate and initialize it using the new operator and the name of the delegate. In the parentheses of the initialization, pass the name of the function that uses the same syntax as the delegate. You can then return the variable of the delegate. Here ia an example:
using System;
using System.Windows.Forms;
namespace Exercises
{
delegate void Observation();
public partial class Form1 : Form
{
public Form1() => InitializeComponent();
void Create() { }
Observation Produce()
{
Observation quote = new Observation(Create);
return quote;
}
}
}
By the way, the variable is useful only if you plan to use the value many times. If not, you can just return the initialization of the delegate. Here is an example:
using System;
using System.Windows.Forms;
namespace Exercises
{
delegate void Observation();
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
void Create() { }
Observation Produce()
{
return new Observation(Create);
}
}
}
Once the function is ready, to use it, you can declare a variable of the type of the delegate and initialize it with the function that returns it. Here is an example:
using System;
using System.Windows.Forms;
namespace Exercises
{
delegate void Observation();
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
void Create()
{
MessageBox.Show("Never let your head hang down. Never give up and sit " +
"down and grieve. Find another way. And don't pray when " +
"it rains if you don't pray when the sun shines. - President Nixon -",
"Citations");
}
Observation Produce()
{
Observation quote = new Observation(Create);
return quote;
}
private void btnQuote_Click(object sender, EventArgs e)
{
Observation obs = Produce();
obs();
}
}
}
Once again, a variable is necessary only you are planning to use the variable more than once. Otherwise, call the function directly where it is needed. This can be done as follows:
using System;
using System.Windows.Forms;
namespace Exercises
{
delegate void Observation();
public partial class Form1 : Form
{
public Form1() => InitializeComponent();
void Create()
{
MessageBox.Show("Never let your head hang down. Never give up and sit " +
"down and grieve. Find another way. And don't pray when " +
"it rains if you don't pray when the sun shines. - President Nixon -",
"Citations");
}
Observation Produce()
{
return new Observation(Create);
}
private void btnCalculate_Click(object sender, EventArgs e)
{
Produce()();
}
}
}
Passing a Parameter-Less Delegate as Parameter
In the previous lesson, we saw how to use a void delegate as a parameter. In the same way, if a delegate is returning a value, it can be used as a parameter. Of course, you should start by creating a delegate that returns a value. If necessary, and in most cases, you should have a function that uses the same syntax as the delegate. Here is an example:
using System.Windows.Forms; namespace Exercises { delegate double Evaluation(); public partial class Exercise : Form { public Exercise() => InitializeComponent(); double Multiply() { return 0.00; } } }
To use the delegate as parameter, create a function that uses a parameter of the type of that delegate. Here is an example:
using System.Windows.Forms; namespace Exercises { delegate double Operation(); public partial class Exercise : Form { public Exercise() { InitializeComponent(); } public double Multiply() { return 0.00; } double Calculate(Operation oper) { return 0.00; } } }
Create a function that returns the delegate type. In the body of the function, you can declare a variable of the delegate and return it. To use the function that returns the delegate type, you can declare a variable of the delegate and assign the function call to it. After that, the delegate variable holds the value that the original delegate is supposed to produce. This whole description can be implemented as follows:
using System; using System.Windows.Forms; namespace Exercises { delegate double Operation(); public partial class Form1 : Form { public Form1() { InitializeComponent(); } double Multiply() { double hourlySalary = double.Parse(txtHourlySalary.Text); double timeWorkedWeek = double.Parse(txtTimeWorked.Text); return hourlySalary * timeWorkedWeek; } Operation Evaluate() { Operation oper = new Operation(Multiply); return oper; } private void btnCalculate_Click(object sender, EventArgs e) { Operation eval = Evaluate(); double netPay = eval(); txtNetPay.Text = netPay.ToString("F"); } } }
Once again, the variables are useful only if you are planning to use their values many times. Otherwise, you can call a function where it is needed. Here are examples:
using System; using System.Windows.Forms; namespace Exercises { delegate double Operation(); public partial class Form1 : Form { public Form1() => InitializeComponent(); double Multiply() { double hourlySalary = double.Parse(txtHourlySalary.Text); double timeWorkedWeek = double.Parse(txtTimeWorked.Text); return hourlySalary * timeWorkedWeek; } Operation Evaluate() { return new Operation(Multiply); } private void btnCalculate_Click(object sender, EventArgs e) { Operation eval = Evaluate(); txtNetPay.Text = eval().ToString("F"); } } }
In fact, the following code works as well:
using System;
using System.Windows.Forms;
namespace Exercises
{
delegate double Operation();
public partial class Form1 : Form
{
public Form1() => InitializeComponent();
double Multiply()
{
return double.Parse(txtHourlySalary.Text) * double.Parse(txtTimeWorked.Text);
}
Operation Evaluate()
{
return new Operation(Multiply);
}
private void btnCalculate_Click(object sender, EventArgs e)
{
txtNetPay.Text = Evaluate()().ToString("F");
}
}
}
Passing a One-Parameter Delegate as Parameter
Imagine you create a delegate function that takes a parameter. You can create a function that return a value of that delegate type. To start, create a function that uses the same syntax as the delegate. Here is an example:
uusing System.Windows.Forms; namespace Exercises { delegate double Operation(double x); public partial class Exercise : Form { public Exercise() { InitializeComponent(); } double Multiply(double time) { return 0.00; } } }
Create a function that returns the type of the delegate.calling the function, pass a function that uses the same syntax as the delegate. Here is an example:
using System.Windows.Forms; namespace Exercises { delegate double Operation(double x); public partial class Exercise : Form { public Exercise() { InitializeComponent(); } public double Multiply(double time) { double hourlySalary = double.Parse(txtHourlySalary.Text); return hourlySalary * time; } Operation Evaluate() { Operation oper = new Operation(Multiply); return oper; } private void btnCalculate_Click(object sender, System.EventArgs e) { Operation calc = Evaluate(); double timeWorkedWeek = double.Parse(txtTimeWorked.Text); double result = calc(timeWorkedWeek); txtNetPay.Text = result.ToString("F"); } } }
Passing a Multi-Parameter Delegate as Parameter
You can create a function that returns a multi-parameters delegate. The steps to follow are the same as those of the previous sections. Here is an example:
using System.Windows.Forms;
namespace Exercises
{
delegate double Operation(double x, double y);
public partial class Exercise : Form
{
public Exercise() => InitializeComponent();
double Multiply(double sal, double time)
{
return sal * time;
}
Operation Evaluate()
{
Operation oper = new Operation(Multiply);
return oper;
}
private void btnCalculate_Click(object sender, System.EventArgs e)
{
Operation calc = Evaluate();
double hourlySalary = double.Parse(txtHourlySalary.Text);
double timeWorkedWeek = double.Parse(txtTimeWorked.Text);
double result = calc(hourlySalary, timeWorkedWeek);
txtNetPay.Text = result.ToString("F");
}
}
}
|
||
Previous | Copyright © 2008-2021, FunctionX | Next |
|