Func<TResult> Gedelegeerde
Definitie
Belangrijk
Bepaalde informatie heeft betrekking op een voorlopige productversie die aanzienlijk kan worden gewijzigd voordat deze wordt uitgebracht. Microsoft biedt geen enkele expliciete of impliciete garanties met betrekking tot de informatie die hier wordt verstrekt.
Kapselt een methode in die geen parameters bevat en retourneert een waarde van het type dat is opgegeven door de TResult parameter.
generic <typename TResult>
public delegate TResult Func();
public delegate TResult Func<out TResult>();
public delegate TResult Func<out TResult>() where TResult : allows ref struct;
public delegate TResult Func<TResult>();
type Func<'Result> = delegate of unit -> 'Result
Public Delegate Function Func(Of Out TResult)() As TResult
Public Delegate Function Func(Of TResult)() As TResult
Type parameters
- TResult
Het type retourwaarde van de methode die door deze gemachtigde wordt ingekapseld.
Dit type parameter is covariant. U kunt het type dat u hebt opgegeven gebruiken of een type dat meer is afgeleid. Zie Covariantie en Contravariantie in Algemene typen voor meer informatie over covariantie en contravariantie.Retourwaarde
De retourwaarde van de methode die door deze gemachtigde wordt ingekapseld.
Voorbeelden
In het volgende voorbeeld ziet u hoe u een gemachtigde gebruikt die geen parameters gebruikt. Met deze code maakt u een algemene klasse met de naam LazyValue die een veld van het type Func<TResult>heeft. Dit gedelegeerde veld kan een verwijzing opslaan naar een functie die een waarde retourneert van het type dat overeenkomt met de typeparameter van het LazyValue object. Het LazyValue type heeft ook een Value eigenschap waarmee de functie wordt uitgevoerd (als deze nog niet is uitgevoerd) en wordt de resulterende waarde geretourneerd.
In het voorbeeld worden twee methoden gemaakt en worden twee LazyValue objecten geïnstitueert met lambda-expressies die deze methoden aanroepen. De lambda-expressies nemen geen parameters omdat ze alleen een methode moeten aanroepen. Zoals in de uitvoer wordt weergegeven, worden de twee methoden alleen uitgevoerd wanneer de waarde van elk LazyValue object wordt opgehaald.
using System;
static class Func1
{
public static void Main()
{
// Note that each lambda expression has no parameters.
LazyValue<int> lazyOne = new LazyValue<int>(() => ExpensiveOne());
LazyValue<long> lazyTwo = new LazyValue<long>(() => ExpensiveTwo("apple"));
Console.WriteLine("LazyValue objects have been created.");
// Get the values of the LazyValue objects.
Console.WriteLine(lazyOne.Value);
Console.WriteLine(lazyTwo.Value);
}
static int ExpensiveOne()
{
Console.WriteLine("\nExpensiveOne() is executing.");
return 1;
}
static long ExpensiveTwo(string input)
{
Console.WriteLine("\nExpensiveTwo() is executing.");
return (long)input.Length;
}
}
class LazyValue<T> where T : struct
{
private Nullable<T> val;
private Func<T> getValue;
// Constructor.
public LazyValue(Func<T> func)
{
val = null;
getValue = func;
}
public T Value
{
get
{
if (val == null)
// Execute the delegate.
val = getValue();
return (T)val;
}
}
}
/* The example produces the following output:
LazyValue objects have been created.
ExpensiveOne() is executing.
1
ExpensiveTwo() is executing.
5
*/
open System
type LazyValue<'T>(func: Func<'T>) =
let mutable value = ValueNone
member _.Value =
match value with
| ValueSome v -> v
| ValueNone ->
// Execute the delegate.
let v = func.Invoke()
value <- ValueSome v
v
let expensiveOne () =
printfn "\nExpensiveOne() is executing."
1
let expensiveTwo (input: string) =
printfn "\nExpensiveTwo() is executing."
int64 input.Length
// Note that each lambda expression has no parameters.
let lazyOne = LazyValue(fun () -> expensiveOne ())
let lazyTwo = LazyValue(fun () -> expensiveTwo "apple")
printfn "LazyValue objects have been created."
// Get the values of the LazyValue objects.
printfn $"{lazyOne.Value}"
printfn $"{lazyTwo.Value}"
// The example produces the following output:
// LazyValue objects have been created.
//
// ExpensiveOne() is executing.
// 1
//
// ExpensiveTwo() is executing.
// 5
Public Module Func
Public Sub Main()
' Note that each lambda expression has no parameters.
Dim lazyOne As New LazyValue(Of Integer)(Function() ExpensiveOne())
Dim lazyTwo As New LazyValue(Of Long)(Function() ExpensiveTwo("apple"))
Console.WriteLine("LazyValue objects have been created.")
' Get the values of the LazyValue objects.
Console.WriteLine(lazyOne.Value)
Console.WriteLine(lazyTwo.Value)
End Sub
Public Function ExpensiveOne() As Integer
Console.WriteLine()
Console.WriteLine("ExpensiveOne() is executing.")
Return 1
End Function
Public Function ExpensiveTwo(input As String) As Long
Console.WriteLine()
Console.WriteLine("ExpensiveTwo() is executing.")
Return input.Length
End Function
End Module
Public Class LazyValue(Of T As Structure)
Private val As Nullable(Of T)
Private getValue As Func(Of T)
' Constructor.
Public Sub New(func As Func(Of T))
Me.val = Nothing
Me.getValue = func
End Sub
Public ReadOnly Property Value() As T
Get
If Me.val Is Nothing Then
' Execute the delegate.
Me.val = Me.getValue()
End If
Return CType(val, T)
End Get
End Property
End Class
Opmerkingen
U kunt deze gemachtigde gebruiken om een methode te vertegenwoordigen die als parameter kan worden doorgegeven zonder expliciet een aangepaste gemachtigde te declareren. De ingekapselde methode moet overeenkomen met de methodehandtekening die door deze gemachtigde is gedefinieerd. Dit betekent dat de ingekapselde methode geen parameters mag hebben en een waarde moet retourneren.
Note
Als u wilt verwijzen naar een methode met geen parameters en void (unit, in F#) (of in Visual Basic, die wordt gedeclareerd als een Sub in plaats van als een Function), gebruikt u in plaats daarvan de Action gedelegeerde.
Wanneer u de Func<TResult> gemachtigde gebruikt, hoeft u niet expliciet een gemachtigde te definiëren die een parameterloze methode inkapselt. De volgende code declareert bijvoorbeeld expliciet een gemachtigde met de naam WriteMethod en wijst een verwijzing naar de instantiemethode toe aan het OutputTarget.SendToFile gemachtigde exemplaar.
using System;
using System.IO;
delegate bool WriteMethod();
public class TestDelegate
{
public static void Main()
{
OutputTarget output = new OutputTarget();
WriteMethod methodCall = output.SendToFile;
if (methodCall())
Console.WriteLine("Success!");
else
Console.WriteLine("File write operation failed.");
}
}
public class OutputTarget
{
public bool SendToFile()
{
try
{
string fn = Path.GetTempFileName();
StreamWriter sw = new StreamWriter(fn);
sw.WriteLine("Hello, World!");
sw.Close();
return true;
}
catch
{
return false;
}
}
}
open System.IO
type WriteMethod = delegate of unit -> bool
type OutputTarget() =
member _.SendToFile() =
try
let fn = Path.GetTempFileName()
use sw = new StreamWriter(fn)
sw.WriteLine "Hello, World!"
true
with _ ->
false
let output = new OutputTarget()
let methodCall = WriteMethod output.SendToFile
if methodCall.Invoke() then
printfn "Success!"
else
printfn "File write operation failed."
Imports System.IO
Delegate Function WriteMethod As Boolean
Module TestDelegate
Public Sub Main()
Dim output As New OutputTarget()
Dim methodCall As WriteMethod = AddressOf output.SendToFile
If methodCall() Then
Console.WriteLine("Success!")
Else
Console.WriteLine("File write operation failed.")
End If
End Sub
End Module
Public Class OutputTarget
Public Function SendToFile() As Boolean
Try
Dim fn As String = Path.GetTempFileName
Dim sw As StreamWriter = New StreamWriter(fn)
sw.WriteLine("Hello, World!")
sw.Close
Return True
Catch
Return False
End Try
End Function
End Class
In het volgende voorbeeld wordt deze code vereenvoudigd door de Func<TResult> gemachtigde te instantiëren in plaats van expliciet een nieuwe gemachtigde te definiëren en er een benoemde methode aan toe te wijzen.
using System;
using System.IO;
public class TestDelegate
{
public static void Main()
{
OutputTarget output = new OutputTarget();
Func<bool> methodCall = output.SendToFile;
if (methodCall())
Console.WriteLine("Success!");
else
Console.WriteLine("File write operation failed.");
}
}
public class OutputTarget
{
public bool SendToFile()
{
try
{
string fn = Path.GetTempFileName();
StreamWriter sw = new StreamWriter(fn);
sw.WriteLine("Hello, World!");
sw.Close();
return true;
}
catch
{
return false;
}
}
}
open System
open System.IO
type OutputTarget() =
member _.SendToFile() =
try
let fn = Path.GetTempFileName()
use sw = new StreamWriter(fn)
sw.WriteLine "Hello, World!"
true
with _ ->
false
let output = OutputTarget()
let methodCall = Func<bool> output.SendToFile
if methodCall.Invoke() then
printfn "Success!"
else
printfn "File write operation failed."
Imports System.IO
Module TestDelegate
Public Sub Main()
Dim output As New OutputTarget()
Dim methodCall As Func(Of Boolean) = AddressOf output.SendToFile
If methodCall() Then
Console.WriteLine("Success!")
Else
Console.WriteLine("File write operation failed.")
End If
End Sub
End Module
Public Class OutputTarget
Public Function SendToFile() As Boolean
Try
Dim fn As String = Path.GetTempFileName
Dim sw As StreamWriter = New StreamWriter(fn)
sw.WriteLine("Hello, World!")
sw.Close
Return True
Catch
Return False
End Try
End Function
End Class
U kunt de Func<TResult> gemachtigde gebruiken met anonieme methoden in C#, zoals in het volgende voorbeeld wordt geïllustreerd. (Zie Anonieme methoden voor een inleiding tot anonieme methoden.)
using System;
using System.IO;
public class Anonymous
{
public static void Main()
{
OutputTarget output = new OutputTarget();
Func<bool> methodCall = delegate() { return output.SendToFile(); };
if (methodCall())
Console.WriteLine("Success!");
else
Console.WriteLine("File write operation failed.");
}
}
public class OutputTarget
{
public bool SendToFile()
{
try
{
string fn = Path.GetTempFileName();
StreamWriter sw = new StreamWriter(fn);
sw.WriteLine("Hello, World!");
sw.Close();
return true;
}
catch
{
return false;
}
}
}
U kunt ook een lambda-expressie toewijzen aan een Func<T,TResult> gemachtigde, zoals in het volgende voorbeeld wordt geïllustreerd. (Zie Lambda-expressies (VB), Lambda-expressies (C#) en Lambda-expressies (F#) voor een inleiding tot lambda-expressies.)
using System;
using System.IO;
public class Anonymous
{
public static void Main()
{
OutputTarget output = new OutputTarget();
Func<bool> methodCall = () => output.SendToFile();
if (methodCall())
Console.WriteLine("Success!");
else
Console.WriteLine("File write operation failed.");
}
}
public class OutputTarget
{
public bool SendToFile()
{
try
{
string fn = Path.GetTempFileName();
StreamWriter sw = new StreamWriter(fn);
sw.WriteLine("Hello, World!");
sw.Close();
return true;
}
catch
{
return false;
}
}
}
open System
open System.IO
type OutputTarget() =
member _.SendToFile() =
try
let fn = Path.GetTempFileName()
use sw = new StreamWriter(fn)
sw.WriteLine "Hello, World!"
true
with _ ->
false
let output = OutputTarget()
let methodCall = Func<bool>(fun () -> output.SendToFile())
if methodCall.Invoke() then
printfn "Success!"
else
printfn "File write operation failed."
Imports System.IO
Module TestDelegate
Public Sub Main()
Dim output As New OutputTarget()
Dim methodCall As Func(Of Boolean) = Function() output.SendToFile()
If methodCall() Then
Console.WriteLine("Success!")
Else
Console.WriteLine("File write operation failed.")
End If
End Sub
End Module
Public Class OutputTarget
Public Function SendToFile() As Boolean
Try
Dim fn As String = Path.GetTempFileName
Dim sw As StreamWriter = New StreamWriter(fn)
sw.WriteLine("Hello, World!")
sw.Close
Return True
Catch
Return False
End Try
End Function
End Class
Het onderliggende type lambda-expressie is een van de algemene Func gemachtigden. Dit maakt het mogelijk om een lambda-expressie als parameter door te geven zonder deze expliciet toe te wijzen aan een gemachtigde. Omdat veel typen typen in de System.Linq naamruimte parameters hebben Func , kunt u deze methoden een lambda-expressie doorgeven zonder expliciet een Func gemachtigde te instantiëren.
Als u een dure berekening hebt die u alleen wilt uitvoeren als het resultaat daadwerkelijk nodig is, kunt u de dure functie toewijzen aan een Func<TResult> gemachtigde. De uitvoering van de functie kan vervolgens worden uitgesteld totdat een eigenschap die toegang heeft tot de waarde, wordt gebruikt in een expressie. In het voorbeeld in de volgende sectie ziet u hoe u dit doet.
Extensiemethoden
| Name | Description |
|---|---|
| GetMethodInfo(Delegate) |
Hiermee haalt u een object op dat de methode vertegenwoordigt die wordt vertegenwoordigd door de opgegeven gemachtigde. |