Dieser Artikel wurde maschinell übersetzt. Wenn Sie die englische Version des Artikels anzeigen möchten, aktivieren Sie das Kontrollkästchen Englisch. Sie können den englischen Text auch in einem Popupfenster anzeigen, indem Sie den Mauszeiger über den Text bewegen.
Übersetzung
Englisch

Func<TResult>-Delegat

 

Veröffentlicht: Oktober 2016

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

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

public delegate TResult Func<out TResult>()

Rückgabewert

Type: TResult

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

Typparameter

outTResult

Der Typ des Rückgabewerts 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. Der gekapselte Methode muss der Methodensignatur entsprechen, die von diesem Delegaten definiert ist. Dies bedeutet, dass der gekapselte Methode keine Parameter erforderlich und muss einen Wert zurückgeben.

System_CAPS_noteHinweis

Um eine Methode zu verweisen, hat keine Parameter und gibt void (oder in Visual Basic deklariert wird als eine Sub sondern als eine Function), verwenden die Action stattdessen delegieren.

Bei Verwendung der Func<TResult> Delegaten, Sie müssen nicht explizit einen Delegaten definieren, der eine parameterlose Methode kapselt. Der folgende Code deklariert beispielsweise explizit einen Delegaten mit dem Namen WriteMethod und weist einen Verweis auf die OutputTarget.SendToFile Instanzmethode-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 folgende Beispiel wird dieser Code vereinfacht, durch die Instanziierung der Func<TResult> Delegaten nicht explizit einen neuen Delegaten definieren und 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 die Func<TResult> -Delegaten mit anonymen Methoden in c#, wie im folgenden Beispiel veranschaulicht. (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 auch einen Lambda-Ausdruck zuweisen einer Func<T, TResult> zu delegieren, wie im folgenden Beispiel veranschaulicht. (Eine Einführung in Lambda-Ausdrücke finden Sie unter Lambda Expressions (Visual Basic) 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. Dadurch können einen Lambda-Ausdruck als Parameter zu übergeben, ohne explizit einen Delegaten zugewiesen werden. Insbesondere, da viele Methoden von Typen in der System.Linq -Namespace haben Func Parameter können übergeben dieser Methoden einen Lambda-Ausdruck ohne explizit zu instanziieren einer Func delegieren.

Wenn Sie eine aufwändige Berechnungen, die Sie möchten nur ausgeführt verfügen, wenn das Ergebnis tatsächlich benötigt wird, können Sie die rechenintensive Funktion Zuweisen einer Func<TResult> delegieren. Die Ausführung der Funktion kann dann verzögert werden, bis eine Eigenschaft, die auf den Wert zugreift, in einem Ausdruck verwendet wird. Im Beispiel im nächsten Abschnitt veranschaulicht dies.

Im folgenden Beispiel wird veranschaulicht, wie ein Delegat zu verwenden, die keine Parameter akzeptiert. Dieser Code erstellt eine generische Klasse namens LazyValue bei dem ein Feld vom Typ Func<TResult>. Dieses Delegatfeld kann speichern einen Verweis auf jede Funktion, die den Typparameter des Typs, entspricht der Wert wieder der LazyValue Objekt. Die LazyValue -Typ weist außerdem eine Value -Eigenschaft, die die Funktion ausführt (sofern sie nicht bereits ausgeführt wurde) und der resultierende Wert zurückgegeben.

Im Beispiel zwei Methoden erstellt und instanziiert Sie zwei LazyValue Objekte mit Lambda-Ausdrücken, die diese Methoden aufrufen. Die Lambda-Ausdrücke nehmen keine Parameter an, da sie nur eine Methode aufrufen müssen. Die zwei Methoden werden ausgeführt, wie die Ausgabe zeigt, nur, wenn der Wert von jedem LazyValue Objekt 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
*/    

Universelle Windows-Plattform
Verfügbar seit 8
.NET Framework
Verfügbar seit 3.5
Portierbare Klassenbibliothek
Unterstützt in: portierbare .NET-Plattformen
Silverlight
Verfügbar seit 2.0
Windows Phone Silverlight
Verfügbar seit 7.0
Windows Phone
Verfügbar seit 8.1
Zurück zum Anfang
Anzeigen: