Func<TResult> Delegát

Definice

Zapouzdřuje metodu, která nemá žádné parametry a vrací hodnotu typu určeného parametrem TResult .

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

Parametry typu

TResult

Typ návratové hodnoty metody, kterou tento delegát zapouzdřuje.

Tento parametr typu je kovariantní. To znamená, že můžete použít buď zadaný typ, nebo libovolný typ, který je více odvozený. Další informace o kovarianci a kontravarianci najdete v tématu popisujícím kovarianci a kontravarianci u parametrického polymorfismu.

Návratová hodnota

TResult

Návratová hodnota metody, kterou tento delegát zapouzdřuje.

Příklady

Následující příklad ukazuje, jak použít delegáta, který neobsahuje žádné parametry. Tento kód vytvoří obecnou třídu s názvem LazyValue , která má pole typu Func<TResult>. Toto pole delegáta může uložit odkaz na libovolnou funkci, která vrátí hodnotu typu, která odpovídá parametru typu objektu LazyValue . Typ LazyValueValue také vlastnost, která spustí funkci (pokud ještě nebyla provedena) a vrátí výslednou hodnotu.

Příklad vytvoří dvě metody a vytvoří instanci dvou LazyValue objektů pomocí výrazů lambda, které tyto metody volají. Výrazy lambda nepřebírají parametry, protože stačí volat metodu. Jak ukazuje výstup, tyto dvě metody se spustí pouze v případě, že se načte hodnota každého LazyValue objektu.

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

Poznámky

Tento delegát můžete použít k reprezentaci metody, která se dá předat jako parametr bez explicitního deklarování vlastního delegáta. Zapouzdřená metoda musí odpovídat podpisu metody definované tímto delegátem. To znamená, že zapouzdřená metoda nesmí mít žádné parametry a musí vrátit hodnotu.

Poznámka

Chcete-li odkazovat na metodu, která nemá žádné parametry a vrací void (v jazyce F#) (unitnebo v Visual Basic, která je deklarována jako místo jako ), Sub Functionpoužijte místo toho delegátaAction.

Při použití delegáta Func<TResult> nemusíte explicitně definovat delegáta, který zapouzdřuje metodu bez parametrů. Následující kód například explicitně deklaruje delegáta pojmenovaného WriteMethod a přiřadí odkaz na metodu OutputTarget.SendToFile instance její instanci delegáta.

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

Následující příklad tento kód zjednodušuje vytvořením instance delegáta Func<TResult> místo explicitního definování nového delegáta a přiřazením pojmenované metody k němu.

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

Delegáta můžete použít Func<TResult> s anonymními metodami v jazyce C#, jak ukazuje následující příklad. (Úvod k anonymním metodám najdete v tématu Anonymní metody.)

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

Výraz lambda můžete také přiřadit delegátu Func<T,TResult> , jak ukazuje následující příklad. (Úvod k výrazům lambda najdete v tématu Výrazy lambda (VB), výrazy lambda (C#) a výrazy lambda (F#).)

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

Základní typ výrazu lambda je jedním z obecných Func delegátů. To umožňuje předat výraz lambda jako parametr, aniž byste ho explicitně přiřadili delegátu. Zejména proto, že mnoho metod typů v System.Linq oboru názvů má Func parametry, můžete tyto metody předat výraz lambda, aniž byste explicitně vytvořili instanci delegáta Func .

Pokud máte drahý výpočet, který chcete provést pouze v případě, že je výsledek skutečně potřebný, můžete přiřadit nákladnou funkci delegátu Func<TResult> . Spuštění funkce se pak může zpozdit, dokud se vlastnost, která přistupuje k hodnotě, použije ve výrazu. Příklad v další části ukazuje, jak to udělat.

Metody rozšíření

GetMethodInfo(Delegate)

Získá objekt, který představuje metodu reprezentovanou zadaným delegátem.

Platí pro

Viz také