Func<TResult> Delegát

Definice

Zapouzdřuje metodu, která nemá žádné parametry a vrací hodnotu typu určeného TResult parametrem .

generic <typename TResult>
public delegate TResult Func();
public delegate TResult Func<out TResult>();
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 

Parametry typu

TResult

Typ návratové hodnoty metody zapouzdřené tímto delegátem.

Tento parametr typu je kovariantní. To znamená, že můžete použít buď zadaný typ, nebo libovolný typ, který je více odvozený. Další informace o kovarianci a kontravarianci najdete v tématu popisujícím kovarianci a kontravarianci u parametrického polymorfismu.

Návratová hodnota

TResult

Návratová hodnota metody zapouzdřené tímto delegátem.

Příklady

Následující příklad ukazuje, jak použít delegáta, který přebírá žádné parametry. Tento kód vytvoří obecnou třídu s LazyValue názvem , která má pole typu Func<TResult> . Toto pole delegáta může ukládat odkaz na libovolnou funkci, která vrací hodnotu typu, která odpovídá parametru LazyValue typu objektu. Typ má také vlastnost, která spustí funkci (pokud ještě nebyla provedena) a vrátí LazyValue Value výslednou hodnotu.

Příklad vytvoří dvě metody a vytvoří instanci dvou LazyValue objektů pomocí výrazů lambda, které tyto metody volají. Výrazy lambda nepřichytá parametry, protože stačí volat metodu. Jak ukazuje výstup, tyto dvě metody se spustí pouze při načtení hodnoty každého LazyValue objektu.

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
*/
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

Poznámky

Tento delegát můžete použít k reprezentaci metody, která může být předána jako parametr bez explicitního deklarování vlastního delegáta. Zapouzdřená metoda musí odpovídat podpisu metody, který je definován tímto delegátem. To znamená, že zapouzdřená metoda nesmí mít žádné parametry a musí vracet hodnotu.

Poznámka

Chcete-li odkazovat na metodu, která nemá žádné parametry a vrací (nebo v Visual Basic, která je deklarována jako místo jako ), použijte místo toho void Sub Function Action delegát.

Při použití Func<TResult> delegátu není nutné explicitně definovat delegát, který zapouzdřuje metodu bez parametrů. Například následující kód explicitně deklaruje delegáta s názvem a přiřadí odkaz na metodu instance instanci WriteMethod OutputTarget.SendToFile delegáta.

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;
      }
   }
}
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

Následující příklad tento kód zjednodušuje vytvořením instance delegáta namísto explicitního definování nového delegáta Func<TResult> a přiřazením pojmenované metody.

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;
      }
   }
}
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

Delegát můžete použít s Func<TResult> anonymními metodami v jazyce C#, jak ukazuje následující příklad. (Úvod do anonymních metod najdete v tématu Anonymní metody.)

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;
      }
   }
}

Můžete také přiřadit výraz lambda Func<T,TResult> delegátu, jak ukazuje následující příklad. (Úvod do výrazů lambda najdete v tématu Výrazy lambda a výrazy lambda.)

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;
      }
   }
}
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

Základní typ výrazu lambda je jedním z obecných Func delegátů. To umožňuje předat výraz lambda jako parametr bez explicitního přiřazení delegátu. Vzhledem k tomu, že mnoho metod typů v oboru názvů má parametry, můžete tyto metody předat výraz lambda bez explicitního vytvoření instance System.Linq Func Func delegáta.

Pokud máte nákladný výpočet, který chcete provést pouze v případě, že je výsledek skutečně potřeba, můžete nákladnou funkci přiřadit Func<TResult> delegátovi. Provádění funkce se pak může zpozdit, dokud se ve výrazu nepouží vlastnost, která přistupuje k hodnotě. Příklad v další části ukazuje, jak to provést.

Metody rozšíření

GetMethodInfo(Delegate)

Získává objekt, který představuje metodu reprezentovanou zadaným delegátem.

Platí pro

Viz také