Lire en anglais

Partager via


Func<TResult> Délégué

Définition

Encapsule une méthode qui n’a pas de paramètre et retourne une valeur du type spécifié par le paramètre TResult.

C#
public delegate TResult Func<out TResult>();
C#
public delegate TResult Func<TResult>();

Paramètres de type

TResult

Type de la valeur de retour de la méthode encapsulée par ce délégué.

Ce paramètre de type est covariant. Cela signifie que vous pouvez utiliser le type spécifié ou tout type plus dérivé. Pour plus d’informations sur la covariance et la contravariance, consultez Covariance et contravariance dans les génériques.

Valeur renvoyée

TResult

Valeur de retour de la méthode encapsulée par ce délégué.

Exemples

L’exemple suivant montre comment utiliser un délégué qui ne prend aucun paramètre. Ce code crée une classe générique nommée LazyValue qui a un champ de type Func<TResult>. Ce champ délégué peut stocker une référence à n’importe quelle fonction qui retourne une valeur du type qui correspond au paramètre de type de l’objet LazyValue . Le LazyValue type a également une Value propriété qui exécute la fonction (si elle n’a pas déjà été exécutée) et retourne la valeur obtenue.

L’exemple crée deux méthodes et instancie deux LazyValue objets avec des expressions lambda qui appellent ces méthodes. Les expressions lambda ne prennent pas de paramètres, car elles doivent simplement appeler une méthode. Comme le montre la sortie, les deux méthodes sont exécutées uniquement lorsque la valeur de chaque LazyValue objet est récupérée.

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

Remarques

Vous pouvez utiliser ce délégué pour représenter une méthode qui peut être transmise en tant que paramètre sans déclarer explicitement un délégué personnalisé. La méthode encapsulée doit correspondre à la signature de méthode définie par ce délégué. Cela signifie que la méthode encapsulée ne doit pas avoir de paramètres et doit retourner une valeur.

Note

Pour référencer une méthode qui n’a aucun paramètre et retourne void (, en F#) (unitou dans Visual Basic, déclarée comme un Sub plutôt que comme un Function), utilisez le délégué à la Action place.

Lorsque vous utilisez le Func<TResult> délégué, vous n’avez pas besoin de définir explicitement un délégué qui encapsule une méthode sans paramètre. Par exemple, le code suivant déclare explicitement un délégué nommé WriteMethod et affecte une référence à la OutputTarget.SendToFile méthode d’instance à son instance déléguée.

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

L’exemple suivant simplifie ce code en instanciant le Func<TResult> délégué au lieu de définir explicitement un nouveau délégué et d’affecter une méthode nommée à celle-ci.

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

Vous pouvez utiliser le délégué avec des méthodes anonymes en C#, comme l’illustre l’exemple Func<TResult> suivant. (Pour une présentation des méthodes anonymes, consultez Méthodes anonymes.)

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

Vous pouvez également affecter une expression lambda à un Func<T,TResult> délégué, comme l’illustre l’exemple suivant. (Pour une introduction aux expressions lambda, consultez Expressions lambda (VB), Expressions lambda (C#) et Expressions lambda (F#).)

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

Le type sous-jacent d’une expression lambda est l’un des délégués génériques Func . Cela permet de passer une expression lambda en tant que paramètre sans l’affecter explicitement à un délégué. En particulier, étant donné que de nombreuses méthodes de types de l’espace System.Linq de noms ont Func des paramètres, vous pouvez passer ces méthodes une expression lambda sans instancier explicitement un Func délégué.

Si vous avez un calcul coûteux que vous souhaitez exécuter uniquement si le résultat est réellement nécessaire, vous pouvez affecter la fonction coûteuse à un Func<TResult> délégué. L’exécution de la fonction peut ensuite être retardée jusqu’à ce qu’une propriété qui accède à la valeur soit utilisée dans une expression. L’exemple de la section suivante montre comment procéder.

Méthodes d’extension

GetMethodInfo(Delegate)

Obtient un objet qui représente la méthode représentée par le délégué spécifié.

S’applique à

Produit Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7
.NET Framework 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

Voir aussi