A Delegate as a Function

Introduction

A function is an action that 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:

delegate double Evaluation();

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 done for a class (a record or a structure) with 0 or a default constructor. In the parentheses, pass the name of the function. Here is an example:

double Calculate()
{
    return 0.00;
}

Evaluation eval = new Evaluation(Calculate);

delegate double Evaluation();

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:

double Calculate()
{
    return 0.00;
}

Evaluation eval = new Evaluation(Calculate);

double weeklySalary = eval();

delegate double Evaluation();

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 static System.Console;

double Calculate()
{
    Write("Hourly Salary: ");
    double hSalary = double.Parse(ReadLine()!);
    Write("Time Worked:   ");
    double tWorked = double.Parse(ReadLine()!);

    double wSalary = hSalary * tWorked;

    return wSalary;
}

Evaluation eval = new Evaluation(Calculate);

double wage = eval();

WriteLine("Net Pay:       " +  wage.ToString("F"));

delegate double Evaluation();

Here is an example of running the program:

Hourly Salary: 17.82
Time Worked:   36.50
Net Pay:       650.43

Press any key to close this window . . .

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:

double Calculate()
{
    Console.Write("Hourly Salary: ");
    double hSalary = double.Parse(Console.ReadLine()!);
    Console.Write("Time Worked:   ");
    double tWorked = double.Parse(Console.ReadLine()!);

    return hSalary * tWorked;
}

Evaluation eval = new Evaluation(Calculate);

Console.WriteLine("Net Pay: " + eval().ToString("F"));

delegate double Evaluation();

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 static System.Console;

double Calculate()
{
    Write("Hourly Salary: ");
    double hSalary = double.Parse(ReadLine()!);
    Write("Time Worked:   ");
    double tWorked = double.Parse(ReadLine()!);

    return hSalary * tWorked;
}

double wage = new Evaluation(Calculate)();

WriteLine("Net Pay: " + wage.ToString("F"));

delegate double Evaluation();

Or as follows:

double Calculate()
{
	Console.Write("Hourly Salary: ");
    double hSalary = double.Parse(Console.ReadLine()!);
    Console.Write("Time Worked:   ");
    double tWorked = double.Parse(Console.ReadLine()!);

    return hSalary * tWorked;
}

Console.WriteLine("Net Pay: " + new Evaluation(Calculate)().ToString("F"));

delegate double Evaluation();

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:

double Calculate()
{
    Console.Write("Hourly Salary: ");
    double hSalary = double.Parse(Console.ReadLine()!);
    Console.Write("Time Worked:   ");
    double tWorked = double.Parse(Console.ReadLine()!);

    return hSalary * tWorked;
}

Evaluation eval = Calculate;

Console.WriteLine("Net Pay: " + eval().ToString("F"));

delegate double Evaluation();

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:

double Calculate(double sal)
{
    return 0.00;
}
    
delegate double Evaluation(double x);

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 static System.Console;

double Calculate(double sal)
{
    Write("Time Worked: ");
    double tWorked = double.Parse(ReadLine()!);

    return sal * tWorked;
}

Write("Hourly Salary: ");
double hSalary = double.Parse(ReadLine()!);

Evaluation eval = new Evaluation(Calculate);

double wage = eval(hSalary);

WriteLine("Net Pay: " + wage.ToString("F"));

delegate double Evaluation(double x);

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 static System.Console;

double Calculate(double sal)
{
    return sal * 40.00;
}

Write("Hourly Salary: ");
double hSalary = double.Parse(ReadLine()!);

double wage = new Evaluation(Calculate)(hSalary);

WriteLine("Net Pay: " + wage.ToString("F"));        

delegate double Evaluation(double x);

In the same way, you may not need a variable to store the value returned by the function delegate. Here is an example:

using static System.Console;

double Calculate(double sal)
{
    return sal * 40.00;
}

Write("Hourly Salary: ");
double hSalary = double.Parse(ReadLine()!);

WriteLine("Net Pay: " + new Evaluation(Calculate)(hSalary).ToString("F"));

delegate double Evaluation(double x);

While we are on the subject of writing brief code, the follow code works as well:

using static System.Console;

double Calculate(double sal)
{
    return sal * 40.00;
}

Write("Hourly Salary: ");

WriteLine("Net Pay: " + new Evaluation(Calculate)(double.Parse(ReadLine()!)).ToString("F");

delegate double Evaluation(double x);

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 static System.Console;

double Calculate(double sal, double time)
{
    return sal * 40.00;
}

Evaluation eval = new Evaluation(Calculate);

Write("Hourly Salary: ");
double hSalary = double.Parse(ReadLine()!);
Write("Time Worked:   ");
double tWorked = double.Parse(ReadLine()!);

double wage = eval(hSalary, tWorked);

WriteLine("Net Pay: " + wage.ToString("F"));

delegate double Evaluation(double x, double y);

Once again, you assign the name of the function to the delegate variable. Here is an example:

using static System.Console;

double Calculate(double sal, double time)
{
    return sal * 40.00;
}

Evaluation eval = Calculate;

Write("Hourly Salary: ");
double hSalary = double.Parse(ReadLine()!);
Write("Time Worked:   ");
double tWorked = double.Parse(ReadLine()!);

double wage = eval(hSalary, tWorked);

WriteLine("------------------------------");
WriteLine("Net Pay:       " + wage.ToString("F"));
WriteLine("================================");

delegate double Evaluation(double x, double y);

In fact, you may not need a variable for the delegate:

using static System.Console;

double Calculate(double sal, double time)
{
    return sal * 40.00;
}

Write("Hourly Salary: ");
double hSalary = double.Parse(ReadLine()!);
Write("Time Worked: ");
double tWorked = double.Parse(ReadLine()!);

double wage = new Evaluation(Calculate)(hSalary, tWorked);

WriteLine("Net Pay: " + wage.ToString("F"));

delegate double Evaluation(double x, double y);

Here is a brief version of the above code:

using static System.Console;

double Calculate(double sal, double time)
{
    return sal * 40.00;
}

Write("Type the hourly salary followed by the time worked: ");

double wage = new Evaluation(Calculate)(double.Parse(ReadLine()!),
                                         double.Parse(ReadLine()!));

WriteLine("------------------------------");
WriteLine("Net Pay:       " + wage.ToString("F"));
WriteLine("================================");

delegate double Evaluation(double x, double y);

Here is an example of running the program:

Type the hourly salary followed by the time worked: 22.25
39.50
------------------------------
Net Pay:       890.00
================================

Press any key to close this window . . .

In the same way, you may not need a variable to store the value returned by the delegate function, like this:

using static System.Console;

double Calculate(double sal, double time)
{
    return sal * 40.00;
}

Write("Hourly Salary: ");
double hSalary = double.Parse(ReadLine()!);
Write("Time Worked:   ");
double tWorked = double.Parse(ReadLine()!);

WriteLine("-----------------------");
WriteLine("Net Pay:       " + (new Evaluation(Calculate)(hSalary, tWorked)).ToString("F"));
WriteLine("=======================");

delegate double Evaluation(double x, double y);

Or like this:

using static System.Console;

delegate double Evaluation(double x, double y);

public class Exercise
{
    double Calculate(double sal, double time)
    {
        return sal * time;
    }

    public static int Main(string[] args)
    {
        WriteLine("Net Pay: " + (new Evaluation(Calculate)(double.Parse(txtHourlySalary.Text),
                                                        double.Parse(txtTimeWorked.Text))).ToString("F"));
        
	return 1_517;
    }
}

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:

Evaluation eval = new Evaluation(Calculate);

double number = eval();

Console.WriteLine("-----------------------");
Console.WriteLine("Net Pay:       " + number.ToString("F"));

double Calculate()
{
    Console.Write("Hourly Salary: ");
    double hSalary = double.Parse(Console.ReadLine()!);
    Console.Write("Time Worked:   ");
    double tWorked = double.Parse(Console.ReadLine()!);

    return hSalary * tWorked;
}

Console.WriteLine("=======================");
        
delegate double Evaluation();

Here is an example of running the program:

Hourly Salary: 17.36
Time Worked:   37.00
-----------------------
Net Pay:       642.32
=======================

Press any key to close this window . . .

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()
{
    Console.Write("Hourly Salary: ");
    double hSalary = double.Parse(Console.ReadLine()!);
    Console.Write("Time Worked: ");
    double tWorked = double.Parse(Console.ReadLine()!);
                
    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:

Evaluation eval = delegate ()
{
    Console.Write("Hourly Salary: ");
    double hSalary = double.Parse(Console.ReadLine()!);
    Console.Write("Time Worked:   ");
    double tWorked = double.Parse(Console.ReadLine()!);

    return hSalary * tWorked;
};

double number = eval();

Console.WriteLine("-----------------------");
Console.WriteLine("Net Pay:       " + number.ToString("F"));
Console.WriteLine("=======================");

delegate double Evaluation();

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:

Evaluation eval = () =>
{
    Console.Write("Hourly Salary: ");
    double hSalary = double.Parse(Console.ReadLine()!);
    Console.Write("Time Worked: ");
    double tWorked = double.Parse(Console.ReadLine()!);
                
    return hSalary * tWorked;
};

double number = eval();

Console.WriteLine("Net Pay: " + number.ToString("F"));

delegate double Evaluation();

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:

Evaluation eval = delegate(double sal)
{
    return sal * 40.00;
};
            
Console.Write("Hourly Salary: ");
double hSalary = double.Parse(Console.ReadLine()!);

double wage = eval(hSalary);

Console.WriteLine("Net Pay: " + wage.ToString("F"));

delegate double Evaluation(double x);

As an alternative, you can omit the delegate keyword but add the => operator after the parentheses. Here is an example:

Evaluation eval = (sal) =>
{
    return sal * 40.00;
};
            
Console.Write("Hourly Salary: ");
double hSalary = double.Parse(Console.ReadLine()!);

double wage = eval(hSalary);

Console.WriteLine("Net Pay: " + wage.ToString("F"));

delegate double Evaluation(double x);

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:

Evaluation eval = new Evaluation(Calculate);

Console.Write("Hourly Salary: ");
double hSalary = double.Parse(Console.ReadLine()!);
Console.Write("Time Worked:   ");
double tWorked = double.Parse(Console.ReadLine()!);

double wage = eval(hSalary, tWorked);

Console.WriteLine("Net Pay:      " + wage.ToString("F"));
            
double Calculate(double sal, double time)
{
    return sal * time;
}

delegate double Evaluation(double x, double y);

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:

Evaluation eval = delegate(double sal, double time)
{
    return sal * time;
};

Console.Write("Hourly Salary: ");
double hSalary = double.Parse(Console.ReadLine()!);
Console.Write("Time Worked:   ");
double tWorked = double.Parse(Console.ReadLine()!);

double wage = eval(hSalary, tWorked);

Console.WriteLine("Net Pay:      " + wage.ToString("F"));

delegate double Evaluation(double x, double y);

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:

Evaluation eval = (double sal, double time) =>
{
    return sal * time;
};

Console.Write("Hourly Salary: ");
double hSalary = double.Parse(Console.ReadLine()!);
Console.Write("Time Worked:   ");
double tWorked = double.Parse(Console.ReadLine()!);

double wage = eval(hSalary, tWorked);

Console.WriteLine("Net Pay: " + wage.ToString("F"));

delegate double Evaluation(double x, double y);

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:

Evaluation eval = (sal, time) =>
{
    return sal * time;
};

Console.Write("Hourly Salary: ");
double hSalary = double.Parse(Console.ReadLine()!);
Console.Write("Time Worked:   ");
double tWorked = double.Parse(Console.ReadLine()!);

double wage = eval(hSalary, tWorked);

Console.WriteLine("Net Pay:      " + wage.ToString("F"));

delegate double Evaluation(double x, double y);

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:

void Create()
{
}

delegate void Observation();

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:

void Create()
{
}

Observation Produce()
{
    return null;
}
    
delegate void Observation();

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:

void Create() { }

Observation Produce()
{
    Observation quote = new Observation(Create);

    return quote;
}

delegate void Observation();

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:

void Create() { }

Observation Produce()
{
    return new(Create);
}
    
delegate void Observation();

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:

void Create()
{
    Console.WriteLine("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 -");
}

Observation Produce()
{
    Observation quote = new Observation(Create);

    return quote;
}

Observation obs = Produce();

obs();


delegate void Observation();

This would produce:

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 -

Press any key to close this window . . .

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:

void Create()
{
    Console.WriteLine("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 -");
}

Observation Produce()
{
    return new Observation(Create);
}

Produce()();

delegate void Observation();

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:

double Multiply()
{
    return 0.00;
}
    
delegate double Evaluation();

To use the delegate as parameter, create a function that uses a parameter of the type of that delegate. Here is an example:

double Multiply()
{
    return 0.00;
}

double Calculate(Operation oper)
{
    return 0.00;
}
    
delegate double Operation();

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:

double Multiply()
{
    Console.Write("Hourly Salary: ");
    double hSalary = double.Parse(Console.ReadLine()!);
    Console.Write("Time Worked:   ");
    double tWorked = double.Parse(Console.ReadLine()!);

    return hSalary * tWorked;
}

Operation Evaluate()
{
    Operation oper = new Operation(Multiply);

    return oper;
}

Operation eval = Evaluate();

double netPay = eval();

Console.WriteLine("Net Pay: " + netPay.ToString("F"));

delegate double Operation();

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:

double Multiply()
{
    Console.Write("Hourly Salary: ");
    double hourlySalary = double.Parse(Console.ReadLine()!);
    Console.Write("Time Worked:   ");
    double timeWorked = double.Parse(Console.ReadLine()!);

    return hourlySalary * timeWorked;
}

Operation Evaluate()
{
    return new Operation(Multiply);
}

Operation eval = Evaluate();

Console.WriteLine("Net Pay: " + eval().ToString("F"));

delegate double Operation();

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:

double Multiply(double time)
{
    return 0.00;
}
    
delegate double Operation(double x);

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:

double Multiply(double time)
{
    Console.Write("Hourly Salary: ");
    double hSalary = double.Parse(Console.ReadLine()!);

    return hSalary * time;
}

Operation Evaluate()
{
    Operation oper = new Operation(Multiply);

    return oper;
}

Operation calc = Evaluate();

Console.Write("Time Worked:   ");
double tWorked = double.Parse(Console.ReadLine()!);

double result = calc(tWorked);

Console.WriteLine("--------------------------");
Console.WriteLine("Net Pay:       " + result.ToString("F"));
Console.WriteLine("==========================");

delegate double Operation(double x);

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:

Operation calc = Evaluate();

Console.Write("Hourly Salary: ");
double hSalary = double.Parse(Console.ReadLine()!);
Console.Write("Time Worked:   ");
double tWorked = double.Parse(Console.ReadLine()!);

double result = calc(hSalary, tWorked);

Console.WriteLine("--------------------------");
Console.WriteLine("Net Pay:       " + result.ToString("F"));
Console.WriteLine("==========================");

double Multiply(double sal, double time)
{
    return sal * time;
}

Operation Evaluate()
{
    Operation oper = new Operation(Multiply);

    return oper;
}

delegate double Operation(double x, double y);

Previous Copyright © 2008-2023, FunctionX Saturday 04 June 2022 Next