Questo articolo è stato tradotto automaticamente. Per visualizzare l'articolo in inglese, selezionare la casella di controllo Inglese. È possibile anche visualizzare il testo inglese in una finestra popup posizionando il puntatore del mouse sopra il testo.
Traduzione
Inglese

Delegato Func<TResult>

 

Data di pubblicazione: novembre 2016

Incapsula un metodo che non presenta alcun parametro e restituisce un valore del tipo specificato dal parametro TResult.

Spazio dei nomi:   System
Assembly:  mscorlib (in mscorlib.dll)

public delegate TResult Func<out TResult>()

Valore restituito

Type: TResult

Valore restituito del metodo incapsulato da questo delegato.

Parametri tipo

outTResult

Tipo del valore restituito del metodo incapsulato da questo delegato.

È possibile utilizzare questo delegato per rappresentare un metodo che può essere passato come parametro senza dichiarare in modo esplicito un delegato personalizzato. Il metodo incapsulato deve corrispondere alla firma del metodo definita da questo delegato. Ciò significa che il metodo incapsulato non deve avere parametri e deve restituire un valore.

System_CAPS_noteNota

Per fare riferimento a un metodo che non dispone di parametri e restituisce void (o in Visual Basic, che è dichiarato come un Sub piuttosto che come un Function), utilizzare il Action delegato.

Quando si utilizza il Func<TResult> delegato, non è necessario definire in modo esplicito un delegato che incapsula un metodo senza parametri. Ad esempio, il codice seguente dichiara in modo esplicito un delegato denominato WriteMethod e assegna un riferimento per il OutputTarget.SendToFile metodo all'istanza di delegato di istanza.

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

Nell'esempio seguente questo codice viene semplificato creando un'istanza di Func<TResult> delegato anziché la definizione di un nuovo delegato e assegnarvi un metodo denominato in modo esplicito.

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

È possibile utilizzare il Func<TResult> delegati con metodi anonimi di c#, come illustrato nell'esempio seguente. (Per un'introduzione ai metodi anonimi, vedere Metodi anonimi (Guida per programmatori 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;
      }
   }
}

È inoltre possibile assegnare un'espressione lambda a un Func<T, TResult> delegato, come illustrato nell'esempio seguente. (Per un'introduzione alle espressioni lambda, vedere Lambda Expressions (Visual Basic) e Espressioni lambda (Guida per programmatori 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;
      }
   }
}

Il tipo sottostante di un'espressione lambda è uno dei generica Func delegati. In questo modo possibile passare un'espressione lambda come un parametro senza assegnarla in modo esplicito un delegato. In particolare, poiché molti metodi dei tipi nel System.Linq dispone di spazio dei nomi Func parametri, è possibile passare questi metodi di un'espressione lambda senza creare un'istanza in modo esplicito un Func delegare.

Se si dispone di un calcolo dispendioso che si desidera eseguire solo se il risultato è veramente necessario, è possibile assegnare la funzione dispendiosa a un Func<TResult> delegare. L'esecuzione della funzione può quindi essere ritardata fino a quando non viene utilizzata una proprietà che accede al valore in un'espressione. Nell'esempio nella sezione successiva viene illustrato come eseguire questa operazione.

Nell'esempio seguente viene illustrato come utilizzare un delegato che non accetta parametri. Questo codice crea una classe generica denominata LazyValue che dispone di un campo di tipo Func<TResult>. Questo campo delegato può archiviare un riferimento a qualsiasi funzione che restituisce un valore del tipo che corrisponde al parametro del tipo di LazyValue oggetto. Il LazyValue tipo dispone anche di un Value proprietà che esegue la funzione (se non è già stata eseguita) e restituisce il valore risultante.

Nell'esempio vengono creati due metodi e un'istanza di due LazyValue oggetti con le espressioni lambda che chiamano questi metodi. Le espressioni lambda non accettano parametri poiché devono semplicemente chiamare un metodo. Come illustrato nell'output, i due metodi vengono eseguiti solo quando il valore di ogni LazyValue oggetto viene recuperato.

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

Universal Windows Platform
Disponibile da 8
.NET Framework
Disponibile da 3.5
Libreria di classi portabile
Supportato in: piattaforme .NET portabili
Silverlight
Disponibile da 2.0
Windows Phone Silverlight
Disponibile da 7.0
Windows Phone
Disponibile da 8.1
Torna all'inizio
Mostra: