Diese Dokumentation wurde archiviert und wird nicht länger gepflegt.

Func<TResult>-Delegat

Aktualisiert: November 2007

Kapselt eine Methode, die über keine Parameter verfügt und einen Wert von dem Typ zurückgibt, der vom TResult-Parameter angegeben wird.

Namespace:  System
Assembly:  System.Core (in System.Core.dll)

public delegate TResult Func<TResult>()

J# unterstützt die Verwendung von generischen APIs, aber nicht die Deklaration von neuen generischen APIs.
JScript unterstützt keine generischen Typen oder Methoden.

Typparameter

TResult

Der Typ des Rückgabewerts der Methode, die dieser Delegat kapselt.

Rückgabewert

Typ: TResult
Der Rückgabewert der Methode, die dieser Delegat kapselt.

Sie können diesen Delegaten verwenden, um eine Methode darzustellen, die als Parameter übergeben werden kann, ohne explizit einen benutzerdefinierten Delegaten zu deklarieren. Die Methode muss der Methodensignatur entsprechen, die von diesem Delegaten definiert wird. Dies bedeutet, dass die gekapselte Methode über keine Parameter verfügen darf und einen Wert zurückgeben muss.

Bb534960.alert_note(de-de,VS.90).gifHinweis:

Um auf eine Methode zu verweisen, die über keine Parameter verfügt und void zurückgibt (oder die in Visual Basic nicht als Function, sondern als Sub deklariert wird), verwenden Sie stattdessen den generischen Action-Delegaten.

Wenn Sie den Func<TResult>-Delegaten verwenden, müssen Sie nicht explizit einen Delegaten definieren, der eine parameterlose Methode kapselt. Der folgende Code deklariert beispielsweise explizit einen Delegaten mit dem Namen WriteMethod und weist der Delegatinstanz einen Verweis auf die OutputTarget.SendToFile-Instanzmethode zu.

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


Im folgenden Beispiel wird dieser Code vereinfacht, indem der Func<TResult>-Delegat instanziiert wird und nicht, indem ein neuer Delegat explizit definiert und diesem eine benannte Methode zugewiesen wird.

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


Sie können den Func<TResult>-Delegaten mit anonymen Methoden in C# verwenden, wie im folgenden Beispiel veranschaulicht wird. (Eine Einführung in anonyme Methoden finden Sie unter Anonyme Methoden (C#-Programmierhandbuch).)

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


Sie können einem Func<T, TResult>-Delegaten auch einen Lambda-Ausdruck zuweisen, wie im folgenden Beispiel veranschaulicht wird. (Eine Einführung in Lambda-Ausdrücke finden Sie unter Lambda-Ausdrücke und Lambda-Ausdrücke (C#-Programmierhandbuch).)

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


Der zugrunde liegende Typ eines Lambda-Ausdrucks ist einer der generischen Func-Delegaten. Hierdurch können Sie einen Lambda-Ausdruck als Parameter übergeben, ohne ihn explizit einem Delegaten zuzuweisen. Da viele Methoden von Typen im System.Linq-Namespace über Func-Parameter verfügen, können Sie diese Methoden als Lambda-Ausdrücke übergeben, ohne explizit einen Func-Delegaten zu instanziieren.

Bei einer umfangreichen Berechnung, die nur dann ausgeführt werden soll, wenn das Ergebnis tatsächlich benötigt wird, können Sie die rechenintensive Funktion einem Func<TResult>-Delegaten zuweisen. Die Ausführung der Funktion kann dann verzögert werden, bis eine Eigenschaft, die auf LazyValue zugreift, in einem Ausdruck verwendet wird. Die entsprechende Vorgehensweise wird im Beispiel des nächsten Abschnitts veranschaulicht.

Im folgenden Beispiel wird veranschaulicht, wie ein Delegat verwendet wird, der keine Parameter annimmt. In diesem Code wird eine generische Klasse mit dem Namen LazyValue erstellt, die über ein Feld vom Typ Func<TResult> verfügt. Dieses Delegatfeld kann einen Verweis auf jede Funktion speichern, die einen Wert des Typs zurückgibt, der dem Typparameter des LazyValue-Objekts entspricht. Der LazyValue-Typ weist außerdem eine Value-Eigenschaft auf, die die Funktion ausführt (sofern sie nicht bereits ausgeführt wurde) und den Ergebniswert zurückgibt.

Im Beispiel werden zwei Methoden erstellt und zwei LazyValue-Objekte mit Lambda-Ausdrücken instanziiert, die diese Methoden aufrufen. Die Lambda-Ausdrücke nehmen keine Parameter an, da sie nur eine Methode aufrufen müssen. Die Ausgabe zeigt, dass die beiden Methoden nur ausgeführt werden, wenn der Wert der einzelnen LazyValue-Objekte abgerufen wird.

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


Windows Vista, Windows XP SP2, Windows Server 2003, Windows CE, Windows Mobile für Smartphone, Windows Mobile für Pocket PC

.NET Framework und .NET Compact Framework unterstützen nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen für .NET Framework.

.NET Framework

Unterstützt in: 3.5

.NET Compact Framework

Unterstützt in: 3.5
Anzeigen: