Ricerca…


Sintassi

  • public delegate TResult Func<in T, out TResult>(T arg)
  • public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2)
  • public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3)
  • public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4)

Parametri

Parametro Dettagli
arg o arg1 il (primo) parametro del metodo
arg2 il secondo parametro del metodo
arg3 il terzo parametro del metodo
arg4 il quarto parametro del metodo
T o T1 il tipo del (primo) parametro del metodo
T2 il tipo del secondo parametro del metodo
T3 il tipo del terzo parametro del metodo
T4 il tipo del quarto parametro del metodo
TResult il tipo di ritorno del metodo

Senza parametri

Questo esempio mostra come creare un delegato che incapsula il metodo che restituisce l'ora corrente

static DateTime UTCNow()
{
    return DateTime.UtcNow;
}

static DateTime LocalNow()
{
    return DateTime.Now;
}

static void Main(string[] args)
{
    Func<DateTime> method = UTCNow;
    // method points to the UTCNow method
    // that retuns current UTC time  
    DateTime utcNow = method();

    method = LocalNow;
    // now method points to the LocalNow method
    // that returns local time

    DateTime localNow = method();
}

Con più variabili

static int Sum(int a, int b)
{
    return a + b;
}

static int Multiplication(int a, int b)
{
    return a * b;
}

static void Main(string[] args)
{
    Func<int, int, int> method = Sum;
    // method points to the Sum method
    // that retuns 1 int variable and takes 2 int variables  
    int sum = method(1, 1);

    method = Multiplication;
    // now method points to the Multiplication method

    int multiplication = method(1, 1);
}

Lambda e metodi anonimi

Un metodo anonimo può essere assegnato ovunque sia previsto un delegato:

Func<int, int> square = delegate (int x) { return x * x; }

Le espressioni Lambda possono essere utilizzate per esprimere la stessa cosa:

Func<int, int> square = x => x * x;

In entrambi i casi, ora possiamo invocare il metodo memorizzato all'interno di un square come questo:

var sq = square.Invoke(2);

O come una stenografia:

var sq = square(2);

Si noti che per l'assegnazione del tipo sicuro, i tipi di parametri e il tipo restituito del metodo anonimo devono corrispondere a quelli del tipo delegato:

Func<int, int> sum = delegate (int x, int y) { return x + y; } // error
Func<int, int> sum = (x, y) => x + y; // error

Parametri di tipo covariant e controvariante

Func supporta anche Covariant & Contravariant

// Simple hierarchy of classes.
public class Person { }
public class Employee : Person { }

class Program
{
    static Employee FindByTitle(String title)
    {
        // This is a stub for a method that returns
        // an employee that has the specified title.
        return new Employee();
    }

    static void Test()
    {
        // Create an instance of the delegate without using variance.
        Func<String, Employee> findEmployee = FindByTitle;

        // The delegate expects a method to return Person,
        // but you can assign it a method that returns Employee.
        Func<String, Person> findPerson = FindByTitle;

        // You can also assign a delegate 
        // that returns a more derived type 
        // to a delegate that returns a less derived type.
        findPerson = findEmployee;

    }
}


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow