.NET Delegates |
|
Introduction to Actions
Overview
We already had an introduction to delegates and we saw how important they are in .NET applications. 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 void function or method. This means that in many cases, instead of creating a 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.Windows.Forms; namespace ActionsFundamentals { public delegate void Observation(); public partial class Form1 : Form { public Form1() { InitializeComponent(); Observation quote = new Observation(HoldConference); quote(); } void HoldConference() { MessageBox.Show("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 -", "Living Quotes"); } } }
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.Windows.Forms; namespace ActionsFundamentals { public partial class Form1 : Form { public Form1() { InitializeComponent(); Action quote = new Action(HoldConference); quote(); } void HoldConference() { MessageBox.Show("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 -", "Living Quotes"); } } }
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.Windows.Forms;
namespace ActionsFundamentals
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Action quote = HoldConference;
quote();
}
void HoldConference()
{
MessageBox.Show("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 -",
"Living Quotes");
}
}
}
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; public class Exercise { public static void Main(string[] args) { Console.Title = "Action Delegates"; Console.WriteLine("Action Delegates"); Console.WriteLine("-----------------"); Action elementaryAlgebra = delegate () { Random rndNumber = new Random(); int number1 = rndNumber.Next(0, 20); int number2 = rndNumber.Next(0, 20); int total = number1 + number2; Console.WriteLine("{0} + {1} = {2}", number1, number2, total); }; elementaryAlgebra(); Console.WriteLine("================================="); } }
Here is an example of running the program:
Action Delegates ----------------- 9 + 12 = 21 ================================= Press any key to continue . . .
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;
public class Exercise
{
public static void Main(string[] args)
{
Console.Title = "Action Delegates";
Console.WriteLine("Action Delegates");
Console.WriteLine("-----------------");
Action elementaryAlgebra = () =>
{
Random rndNumber = new Random();
int number1 = rndNumber.Next(0, 20);
int number2 = rndNumber.Next(0, 20);
int total = number1 + number2;
Console.WriteLine("{0} + {1} = {2}", number1, number2, total);
};
elementaryAlgebra();
Console.WriteLine("=================================");
}
}
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; using System.Windows.Forms; namespace ActionsFundamentals { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnActions_Click(object sender, EventArgs e) { Action<string> quote = new Action<string>(Create); } void Create(string say) { MessageBox.Show(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.Windows.Forms;
namespace DotNETDelegates
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnDelegate_Click(object sender, EventArgs e)
{
Action<string> quote = new Action<string>(Create);
quote("Les dances à la gloire de la fornication.");
}
void Create(string say)
{
MessageBox.Show(say);
}
}
}
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 commas. 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;
using System.Windows.Forms;
namespace ActionsDelegates
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Action Doubler()
{
Action times = new Action(Multiplication);
return times;
}
void Multiplication()
{
Random rndNumber = new Random();
int number1 = rndNumber.Next(0, 10);
int number2 = rndNumber.Next(0, 10);
int total = number1 * number2;
MessageBox.Show(string.Format("{0} + {1} = {2}", number1, number2, total), "Action Delegates");
}
private void btnDelegate_Click(object sender, EventArgs e)
{
Action operation = Doubler();
operation();
}
}
}
In the same way, a method can return a list 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:
public class Exercise
{
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) parameters. 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:
public class Exercise
{
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.Windows.Forms;
namespace ActionsFundamentals
{
public partial class Form1 : Form
{
public Form1() => InitializeComponent();
void Hold()
{
MessageBox.Show("People who live in glass houses should not throw stones.", "Action Delegates");
}
void Create(Action speech)
{
speech();
}
private void btnDelegate_Click(object sender, EventArgs e)
{
Create(Hold);
}
}
}
This would produce:
.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<>.
A Simple Function Delegate
Consider the following code:
using System; using System.Windows.Forms; namespace FunctionsDelegates { delegate double Evaluation(); public partial class Form1 : Form { public Form1() { InitializeComponent(); } double Calculate() { double hSalary = 25.75; double tWorked = 38.50; double wSalary = hSalary * tWorked; return wSalary; } private void btnDelegate_Click(object sender, EventArgs e) { Evaluation eval = new Evaluation(Calculate); MessageBox.Show(string.Format("Number: {0}", eval().ToString("F")), "Action Delegate"); } } }
This would produce:
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 function or method for the delegate, you must indicate the desired return value. To associate the function to the delegate, declare a Func<> variable. Between < and >, include the same return type as the function. Initialize the variable with the name of the function. You can then call the variable as if it were a method. This can be done as follows:
using System; using System.Windows.Forms; namespace FunctionsDelegates { public partial class Form1 : Form { public Form1() { InitializeComponent(); } double Calculate() { double hSalary = 25.75; double tWorked = 38.50; double wSalary = hSalary * tWorked; return wSalary; } private void btnDelegate_Click(object sender, EventArgs e) { Func<double> eval = new Func<double>(Calculate); MessageBox.Show(string.Format("Number: {0}", eval().ToString("F")), "Action Delegate"); } } }
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.Windows.Forms;
namespace FunctionsDelegates
{
public partial class Form1 : Form
{
public Form1() => InitializeComponent();
double Calculate()
{
double hSalary = 25.75;
double tWorked = 38.50;
double wSalary = hSalary * tWorked;
return wSalary;
}
private void btnDelegate_Click(object sender, EventArgs e)
{
Func<double> eval = Calculate;
MessageBox.Show(string.Format("Number: {0}", eval().ToString("F")), "Action Delegate");
}
}
}
We already know that a function that returns one value can return it as a tuple instead. As we know already, tuples make it possible for a function to return many values. This concept also applies to function delegates. Here is an example:
using System; using System.Windows.Forms; namespace FunctionsDelegates { public partial class Form1 : Form { public Form1() { InitializeComponent(); } (string, double, string, double, double) Calculate() { double hSalary = 25.75; double tWorked = 38.50; double wSalary = hSalary * tWorked; return ("Hourly Salary", hSalary, "Time Worked", tWorked, wSalary); } private void btnDelegate_Click(object sender, EventArgs e) { Func<(string, double, string, double, double)> eval = Calculate; MessageBox.Show(string.Format("{0}: {1}\n{2}: {3}\nNet Pay: {4}", eval().Item1, eval().Item2.ToString(), eval().Item3, eval().Item4.ToString("F"), eval().Item5.ToString()), "Action Delegate"); } } }
This would produce:
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.Windows.Forms;
namespace FunctionsDelegates
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnDelegate_Click(object sender, EventArgs e)
{
Func<double> eval = delegate ()
{
double hSalary = 25.75;
double tWorked = 38.50;
double wSalary = hSalary * tWorked;
return wSalary;
};
MessageBox.Show(string.Format("Number {0}: ", eval().ToString("F")),
"Action Delegate");
}
}
}
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.Windows.Forms;
namespace FunctionsDelegates
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnDelegate_Click(object sender, EventArgs e)
{
Func<double> eval = () =>
{
double hSalary = 25.75;
double tWorked = 38.50;
double wSalary = hSalary * tWorked;
return wSalary;
};
MessageBox.Show(string.Format("Number {0}: ", eval().ToString("F")),
"Action Delegate");
}
}
}
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.Windows.Forms; namespace FunctionsDelegates { delegate double Operation(double a); public partial class Form1 : Form { double hourlySalary = 12.75; public Form1() => InitializeComponent(); 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; } } double EvaluateSalary(Operation calc) { return calc(hourlySalary); } private void btnDelegate_Click(object sender, EventArgs e) { Operation oper = Multiply; double dailySalary = EvaluateSalary(oper); MessageBox.Show(string.Format("Daily Salary: {0}", dailySalary.ToString("F")), "Action Delegate"); } } }
This would produce:
To simplify your code, you can use a Func delegate. Instead of this:
using System; using System.Windows.Forms; namespace FunctionsDelegates { delegate double Operation(double a); public partial class Form1 : Form { double hourlySalary = 12.75; public Form1() { InitializeComponent(); } double EvaluateSalary(Operation calc) { return calc(hourlySalary); } private void btnDelegate_Click(object sender, EventArgs e) { 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; } }); MessageBox.Show(string.Format("Daily Salary: {0}", dailySalary.ToString("F")), "Action Delegate"); } } }
You can use this:
using System; using System.Windows.Forms; namespace FunctionsDelegates { public partial class Form1 : Form { double hourlySalary = 12.75; public Form1() { InitializeComponent(); } private void btnDelegate_Click(object sender, EventArgs e) { 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); MessageBox.Show(string.Format("Daily Salary: {0}", dailySalary.ToString("F")), "Action Delegate"); } } }
This would produce:
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.Windows.Forms;
namespace FunctionsDelegates
{
public partial class Form1 : Form
{
double hourlySalary = 12.75;
public Form1()
{
InitializeComponent();
}
private void btnDelegate_Click(object sender, EventArgs e)
{
Func<double, double> Calculate = timeWorked => hourlySalary * timeWorked;
double dailySalary = Calculate(12.00);
MessageBox.Show(string.Format("Daily Salary: {0}", dailySalary.ToString("F")),
"Action Delegate");
}
}
}
This would produce:
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 function or 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;
public class Exercise
{
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;
public class Exercise
{
Func<int> Calculate()
{
Func<int> result = Addition;
return result;
}
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 function or method that returns the function delegate. Here is an example:
using System;
public class Exercise
{
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;
using System.Windows.Forms;
namespace DotNETDelegates
{
public partial class Form1 : Form
{
public Form1() => InitializeComponent();
Func<int> Calculate()
{
Func<int> result = Addition;
return result;
}
int Addition()
{
Random rndNumber = new Random();
int number1 = rndNumber.Next(0, 20);
int number2 = rndNumber.Next(0, 20);
int total = number1 + number2;
return total;
}
private void btnDelegate_Click(object sender, EventArgs e)
{
Func<int> eval = Calculate();
MessageBox.Show(string.Format("Daily Salary: {0}", eval()), "Action Delegate");
}
}
}
This would produce:
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.Windows.Forms;
namespace DotNETDelegates
{
delegate double Operation(double a);
public partial class Form1 : Form
{
double value = 148.86;
public Form1() => InitializeComponent();
double Multiply(double side)
{
return side * side;
}
double Calculate(Operation oper)
{
return oper(value);
}
private void btnDelegate_Click(object sender, EventArgs e)
{
double area = Calculate(Multiply);
MessageBox.Show(string.Format("Area of Cube: {0}", area), "Function Delegate");
}
}
}
This would produce:
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.Windows.Forms;
namespace DotNETDelegates
{
public partial class Form1 : Form
{
double value = 148.86;
public Form1() => InitializeComponent();
double Multiply(double side)
{
return side * side;
}
double Calculate(Func<double, double> oper)
{
return oper(value) * 6.00;
}
private void btnDelegate_Click(object sender, EventArgs e)
{
double area = Calculate(Multiply);
MessageBox.Show(string.Format("Area of Cube: {0}", area), "Function Delegate");
}
}
}
This would produce:
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.Windows.Forms;
namespace DotNETDelegates
{
public partial class Form1 : Form
{
double value = 148.86;
public Form1() => InitializeComponent();
double Calculate(Func<double, double> oper)
{
return oper(value) * 6.00;
}
private void btnDelegate_Click(object sender, EventArgs e)
{
double area = Calculate((double side) =>
{
return side * side;
});
MessageBox.Show(string.Format("Area of Cube: {0}", area), "Function Delegate");
}
}
}
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;
using System.Windows.Forms;
namespace DotNETDelegates
{
public partial class Form1 : Form
{
double value = 148.86;
public Form1() => InitializeComponent();
double Calculate(Func<double, double> oper)
{
return oper(value) * 6.00;
}
private void btnDelegate_Click(object sender, EventArgs e)
{
double area = Calculate(side => side * side);
MessageBox.Show(string.Format("Area of Cube: {0}", area), "Function Delegate");
}
}
}
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 the parentheses. In the parentheses, 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
using System;
using System.Windows.Forms;
namespace FunctionsDelegates
{
public partial class Form1 : Form
{
public Form1() => InitializeComponent();
private void btnDelegate_Click(object sender, EventArgs e)
{
double subTotal = 2425.75;
int shippingAndHanling = 36;
Func<double, double, double> Plus = (a, b) => a + b;
double invoiceTotal = Plus(subTotal, shippingAndHanling);
MessageBox.Show(string.Format("Invoice Total: {0}", invoiceTotal), "Function Delegate");
}
}
}
This would produce:
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.
|
||
Previous | Copyright © 2008-2020, FunctionX | Next |
|