Func<TResult> Func<TResult> Func<TResult> Func<TResult> Delegate

Definición

Encapsula un método que no tiene parámetros y devuelve un valor del tipo especificado por el parámetro TResult.Encapsulates a method that has no parameters and returns a value of the type specified by the TResult parameter.

generic <typename TResult>
public delegate TResult Func();
public delegate TResult Func<out TResult>();
type Func<'Result> = delegate of unit -> 'Result
Public Delegate Function Func(Of Out TResult)() As TResult 

Parámetros de tipo

TResult

Tipo del valor devuelto del método que este delegado encapsula.The type of the return value of the method that this delegate encapsulates.

Valor devuelto

TResult

Valor devuelto del método que este delegado encapsula.The return value of the method that this delegate encapsulates.

Herencia
Func<TResult>Func<TResult>Func<TResult>Func<TResult>

Ejemplos

El ejemplo siguiente muestra cómo usar a un delegado que no toma ningún parámetro.The following example demonstrates how to use a delegate that takes no parameters. Este código crea una clase genérica denominada LazyValue que tiene un campo de tipo Func<TResult>.This code creates a generic class named LazyValue that has a field of type Func<TResult>. Este campo de delegado puede almacenar una referencia a cualquier función que devuelve un valor del tipo que corresponde al parámetro de tipo de la LazyValue objeto.This delegate field can store a reference to any function that returns a value of the type that corresponds to the type parameter of the LazyValue object. El LazyValue tipo también tiene un Value propiedad que se ejecuta la función (si lo no ya se ha ejecutado) y devuelve el valor resultante.The LazyValue type also has a Value property that executes the function (if it has not already been executed) and returns the resulting value.

El ejemplo crea dos métodos y se crean instancias de dos LazyValue objetos con expresiones lambda que llaman a estos métodos.The example creates two methods and instantiates two LazyValue objects with lambda expressions that call these methods. Las expresiones lambda no toman parámetros porque sólo necesitan llamar a un método.The lambda expressions do not take parameters because they just need to call a method. Como se muestra el resultado, los dos métodos se ejecutan solo cuando el valor de cada LazyValue se recupera el objeto.As the output shows, the two methods are executed only when the value of each LazyValue object is retrieved.

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

Comentarios

Este delegado se puede usar para representar un método que se puede pasar como un parámetro sin declarar explícitamente un delegado personalizado.You can use this delegate to represent a method that can be passed as a parameter without explicitly declaring a custom delegate. El método encapsulado debe corresponder a la firma del método que está definida por este delegado.The encapsulated method must correspond to the method signature that is defined by this delegate. Esto significa que el método encapsulado no debe tener ningún parámetro y debe devolver un valor.This means that the encapsulated method must have no parameters and must return a value.

Nota

Hacer referencia a un método que no tiene parámetros y devuelve void (o en Visual Basic, que se declara como un Sub en lugar de como un Function), use el Action delegar en su lugar.To reference a method that has no parameters and returns void (or in Visual Basic, that is declared as a Sub rather than as a Function), use the Action delegate instead.

Cuando se usa el Func<TResult> delegado, no es necesario definir explícitamente un delegado que encapsula un método sin parámetros.When you use the Func<TResult> delegate, you do not have to explicitly define a delegate that encapsulates a parameterless method. Por ejemplo, el código siguiente declara explícitamente un delegado denominado WriteMethod y le asigna una referencia a la OutputTarget.SendToFile método a su instancia de delegado de instancia.For example, the following code explicitly declares a delegate named WriteMethod and assigns a reference to the OutputTarget.SendToFile instance method to its delegate instance.

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

En el ejemplo siguiente se simplifica este código creando instancias de la Func<TResult> delegado en lugar de definir explícitamente un nuevo delegado y asignarle un método con nombre.The following example simplifies this code by instantiating the Func<TResult> delegate instead of explicitly defining a new delegate and assigning a named method to it.

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

Puede usar el Func<TResult> delegar con métodos anónimos en C#, como se muestra en el ejemplo siguiente.You can use the Func<TResult> delegate with anonymous methods in C#, as the following example illustrates. (Para obtener una introducción a los métodos anónimos, consulte métodos anónimos.)(For an introduction to anonymous methods, see Anonymous Methods.)

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

También puede asignar una expresión lambda a un Func<T,TResult> delegado, como se muestra en el ejemplo siguiente.You can also assign a lambda expression to a Func<T,TResult> delegate, as the following example illustrates. (Para obtener una introducción a las expresiones lambda, vea expresiones Lambda y expresiones Lambda.)(For an introduction to lambda expressions, see Lambda Expressions and Lambda Expressions.)

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

El tipo subyacente de una expresión lambda es uno de la clase genérica Func delegados.The underlying type of a lambda expression is one of the generic Func delegates. Esto permite pasar una expresión lambda como un parámetro sin asignar explícitamente a un delegado.This makes it possible to pass a lambda expression as a parameter without explicitly assigning it to a delegate. En concreto, porque muchos métodos de tipos en el System.Linq tiene espacio de nombres Func parámetros, puede pasar estos métodos de una expresión lambda sin crear explícitamente instancias de un Func delegar.In particular, because many methods of types in the System.Linq namespace have Func parameters, you can pass these methods a lambda expression without explicitly instantiating a Func delegate.

Si tiene un cálculo costoso que desea ejecutar solo si realmente se necesita el resultado, puede asignar la función cara a una Func<TResult> delegar.If you have an expensive computation that you want to execute only if the result is actually needed, you can assign the expensive function to a Func<TResult> delegate. A continuación, se puede retrasar la ejecución de la función hasta que una propiedad que tiene acceso al valor se utiliza en una expresión.The execution of the function can then be delayed until a property that accesses the value is used in an expression. El ejemplo en la sección siguiente muestra cómo hacerlo.The example in the next section demonstrates how to do this.

Extension Methods

GetMethodInfo(Delegate) GetMethodInfo(Delegate) GetMethodInfo(Delegate) GetMethodInfo(Delegate)

Obtiene un objeto que representa el método representado por el delegado especificado.Gets an object that represents the method represented by the specified delegate.

Se aplica a

Consulte también: