Func<TResult> Gedelegeerde

Definitie

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

TResult

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.

Van toepassing op

Zie ook