Condividi tramite


Action<T1,T2,T3> Delegato

Definizione

Incapsula un metodo con tre parametri e non restituisce un valore.

generic <typename T1, typename T2, typename T3>
public delegate void Action(T1 arg1, T2 arg2, T3 arg3);
public delegate void Action<in T1,in T2,in T3>(T1 arg1, T2 arg2, T3 arg3);
public delegate void Action<T1,T2,T3>(T1 arg1, T2 arg2, T3 arg3);
type Action<'T1, 'T2, 'T3> = delegate of 'T1 * 'T2 * 'T3 -> unit
Public Delegate Sub Action(Of In T1, In T2, In T3)(arg1 As T1, arg2 As T2, arg3 As T3)
Public Delegate Sub Action(Of T1, T2, T3)(arg1 As T1, arg2 As T2, arg3 As T3)

Parametri di tipo

T1

Tipo del primo parametro del metodo incapsulato da questo delegato.

Questo parametro di tipo è controvariante, ovvero puoi usare il tipo specificato o qualsiasi tipo meno derivato. Per altre informazioni sulla covarianza e la controvarianza, vedi Covarianza e controvarianza nei generics.
T2

Tipo del secondo parametro del metodo incapsulato da questo delegato.

Questo parametro di tipo è controvariante, ovvero puoi usare il tipo specificato o qualsiasi tipo meno derivato. Per altre informazioni sulla covarianza e la controvarianza, vedi Covarianza e controvarianza nei generics.
T3

Tipo del terzo parametro del metodo incapsulato da questo delegato.

Questo parametro di tipo è controvariante, ovvero puoi usare il tipo specificato o qualsiasi tipo meno derivato. Per altre informazioni sulla covarianza e la controvarianza, vedi Covarianza e controvarianza nei generics.

Parametri

arg1
T1

Primo parametro del metodo incapsulato da questo delegato.

arg2
T2

Secondo parametro del metodo incapsulato da questo delegato.

arg3
T3

Terzo parametro del metodo incapsulato da questo delegato.

Commenti

È possibile usare il delegato Action<T1,T2,T3> per passare un metodo come parametro senza dichiarare esplicitamente un delegato personalizzato. Il metodo incapsulato deve corrispondere alla firma del metodo definita da questo delegato. Ciò significa che il metodo incapsulato deve avere tre parametri che vengono tutti passati per valore e non deve restituire un valore. In C# il metodo deve restituire void. In F# il metodo o la funzione deve restituire un'unità. In Visual Basic deve essere definito dal costrutto Sub...End Sub. Può anche essere un metodo che restituisce un valore ignorato. In genere, questo metodo viene usato per eseguire un'operazione.

Nota

Per fare riferimento a un metodo con tre parametri e restituisce un valore, usare invece il delegato generico Func<T1,T2,T3,TResult>.

Quando si usa il delegato Action<T1,T2,T3>, non è necessario definire in modo esplicito un delegato che incapsula un metodo con tre parametri. Ad esempio, il codice seguente dichiara in modo esplicito un delegato denominato StringCopy e assegna un riferimento al metodo CopyStrings all'istanza del delegato.

using System;

delegate void StringCopy(string[] stringArray1,
                         string[] stringArray2,
                         int indexToStart);

public class TestDelegate
{
    public static void Main()
    {
        string[] ordinals = ["First", "Second", "Third", "Fourth", "Fifth"];
        string[] copiedOrdinals = new string[ordinals.Length];
        StringCopy copyOperation = CopyStrings;
        copyOperation(ordinals, copiedOrdinals, 3);
        foreach (string ordinal in copiedOrdinals)
            Console.WriteLine(string.IsNullOrEmpty(ordinal) ? "<None>" : ordinal);
    }

    private static void CopyStrings(string[] source, string[] target, int startPos)
    {
        if (source.Length != target.Length)
            throw new IndexOutOfRangeException("The source and target arrays must have the same number of elements.");

        for (int ctr = startPos; ctr <= source.Length - 1; ctr++)
            target[ctr] = source[ctr];
    }
}
open System

type StringCopy = delegate of stringArray1: string [] * 
                              stringArray2: string [] * 
                              indexToStart: int -> unit

let copyStrings (source: string []) (target: string []) startPos =
    if source.Length <> target.Length then
        raise (IndexOutOfRangeException "The source and target arrays must have the same number of elements.")

    for i = startPos to source.Length - 1 do
        target.[i] <- source.[i]

let ordinals = [| "First"; "Second"; "Third"; "Fourth"; "Fifth" |]
let copiedOrdinals: string [] = Array.zeroCreate ordinals.Length

let copyOperation = StringCopy copyStrings

copyOperation.Invoke(ordinals, copiedOrdinals, 3)

for ordinal in copiedOrdinals do
    printfn "%s" (if String.IsNullOrEmpty ordinal then "<None>" else ordinal)
Delegate Sub StringCopy(stringArray1() As String,
                        stringArray2() As String,
                        indexToStart As Integer)

Module TestDelegate
    Public Sub RunIt()
        Dim ordinals() As String = {"First", "Second", "Third", "Fourth", "Fifth"}
        Dim copiedOrdinals(ordinals.Length - 1) As String
        Dim copyOperation As StringCopy = AddressOf CopyStrings
        copyOperation(ordinals, copiedOrdinals, 3)
        For Each ordinal As String In copiedOrdinals
            If String.IsNullOrEmpty(ordinal) Then
                Console.WriteLine("<None>")
            Else
                Console.WriteLine(ordinal)
            End If
        Next
    End Sub

    Private Sub CopyStrings(source() As String, target() As String, startPos As Integer)
        If source.Length <> target.Length Then
            Throw New IndexOutOfRangeException("The source and target arrays must have the same number of elements.")
        End If
        For ctr As Integer = startPos To source.Length - 1
            target(ctr) = source(ctr)
        Next
    End Sub
End Module

L'esempio seguente semplifica questo codice creando un'istanza del delegato Action<T1,T2,T3> anziché definire in modo esplicito un nuovo delegato e assegnando un metodo denominato.

using System;

public class TestAction3
{
    public static void Main()
    {
        string[] ordinals = ["First", "Second", "Third", "Fourth", "Fifth"];
        string[] copiedOrdinals = new string[ordinals.Length];
        Action<string[], string[], int> copyOperation = CopyStrings;
        copyOperation(ordinals, copiedOrdinals, 3);
        foreach (string ordinal in copiedOrdinals)
            Console.WriteLine(string.IsNullOrEmpty(ordinal) ? "<None>" : ordinal);
    }

    private static void CopyStrings(string[] source, string[] target, int startPos)
    {
        if (source.Length != target.Length)
            throw new IndexOutOfRangeException("The source and target arrays must have the same number of elements.");

        for (int ctr = startPos; ctr <= source.Length - 1; ctr++)
            target[ctr] = source[ctr];
    }
}
open System

let copyStrings (source: string []) (target: string []) startPos =
    if source.Length <> target.Length then
        raise (IndexOutOfRangeException "The source and target arrays must have the same number of elements.")

    for i = startPos to source.Length - 1 do
        target.[i] <- source.[i]

let ordinals = [| "First"; "Second"; "Third"; "Fourth"; "Fifth" |]
let copiedOrdinals = Array.zeroCreate<string> ordinals.Length

let copyOperation = Action<_,_,_> copyStrings

copyOperation.Invoke(ordinals, copiedOrdinals, 3)

for ordinal in copiedOrdinals do
    printfn "%s" (if String.IsNullOrEmpty ordinal then "<None>" else ordinal)
Module TestAction3
    Public Sub RunIt()
        Dim ordinals() As String = {"First", "Second", "Third", "Fourth", "Fifth"}
        Dim copiedOrdinals(ordinals.Length - 1) As String
        Dim copyOperation As Action(Of String(), String(), Integer) = AddressOf CopyStrings
        copyOperation(ordinals, copiedOrdinals, 3)
        For Each ordinal As String In copiedOrdinals
            If String.IsNullOrEmpty(ordinal) Then
                Console.WriteLine("<None>")
            Else
                Console.WriteLine(ordinal)
            End If
        Next
    End Sub

    Private Sub CopyStrings(source() As String, target() As String, startPos As Integer)
        If source.Length <> target.Length Then
            Throw New IndexOutOfRangeException("The source and target arrays must have the same number of elements.")
        End If
        For ctr As Integer = startPos To source.Length - 1
            target(ctr) = source(ctr)
        Next
    End Sub
End Module

È anche possibile usare il delegato Action<T1,T2,T3> con metodi anonimi in C#, come illustrato nell'esempio seguente. Per un'introduzione ai metodi anonimi, vedere metodi anonimi.

using System;

public class TestAnon
{
    public static void Main()
    {
        string[] ordinals = ["First", "Second", "Third", "Fourth", "Fifth"];
        string[] copiedOrdinals = new string[ordinals.Length];
        Action<string[], string[], int> copyOperation = delegate (string[] s1,
                                                                 string[] s2,
                                                                 int pos)
                                        { CopyStrings(s1, s2, pos); };
        copyOperation(ordinals, copiedOrdinals, 3);
        foreach (string ordinal in copiedOrdinals)
            Console.WriteLine(string.IsNullOrEmpty(ordinal) ? "<None>" : ordinal);
    }

    private static void CopyStrings(string[] source, string[] target, int startPos)
    {
        if (source.Length != target.Length)
            throw new IndexOutOfRangeException("The source and target arrays must have the same number of elements.");

        for (int ctr = startPos; ctr <= source.Length - 1; ctr++)
            target[ctr] = source[ctr];
    }
}

È anche possibile assegnare un'espressione lambda a un'istanza del delegato Action<T1,T2,T3>, come illustrato nell'esempio seguente. Per un'introduzione alle espressioni lambda, vedere espressioni lambda (C#) o espressioni lambda (F#).

using System;

public class TestLambda
{
    public static void Main()
    {
        string[] ordinals = ["First", "Second", "Third", "Fourth", "Fifth"];
        string[] copiedOrdinals = new string[ordinals.Length];
        Action<string[], string[], int> copyOperation = (s1, s2, pos) =>
                                        CopyStrings(s1, s2, pos);
        copyOperation(ordinals, copiedOrdinals, 3);
        foreach (string ordinal in copiedOrdinals)
            Console.WriteLine(string.IsNullOrEmpty(ordinal) ? "<None>" : ordinal);
    }

    private static void CopyStrings(string[] source, string[] target, int startPos)
    {
        if (source.Length != target.Length)
            throw new IndexOutOfRangeException("The source and target arrays must have the same number of elements.");

        for (int ctr = startPos; ctr <= source.Length - 1; ctr++)
            target[ctr] = source[ctr];
    }
}
open System

let copyStrings (source: string []) (target: string []) startPos =
    if source.Length <> target.Length then
        raise (IndexOutOfRangeException "The source and target arrays must have the same number of elements.")

    for i = startPos to source.Length - 1 do
        target.[i] <- source.[i]

let ordinals = [| "First"; "Second"; "Third"; "Fourth"; "Fifth" |]
let copiedOrdinals: string [] = Array.zeroCreate ordinals.Length

let copyOperation = Action<_,_,_> (fun s1 s2 pos -> copyStrings s1 s2 pos)

copyOperation.Invoke(ordinals, copiedOrdinals, 3)

for ordinal in copiedOrdinals do
    printfn "%s" (if String.IsNullOrEmpty ordinal then "<None>" else ordinal)
Public Module TestLambda
    Public Sub RunIt()
        Dim ordinals() As String = {"First", "Second", "Third", "Fourth", "Fifth"}
        Dim copiedOrdinals(ordinals.Length - 1) As String
        Dim copyOperation As Action(Of String(), String(), Integer) =
                           Sub(s1, s2, pos) CopyStrings(s1, s2, pos)
        copyOperation(ordinals, copiedOrdinals, 3)
        For Each ordinal As String In copiedOrdinals
            If String.IsNullOrEmpty(ordinal) Then
                Console.WriteLine("<None>")
            Else
                Console.WriteLine(ordinal)
            End If
        Next
    End Sub

    Private Function CopyStrings(source() As String, target() As String, startPos As Integer) As Integer
        If source.Length <> target.Length Then
            Throw New IndexOutOfRangeException("The source and target arrays must have the same number of elements.")
        End If

        For ctr As Integer = startPos To source.Length - 1
            target(ctr) = source(ctr)
        Next
        Return source.Length - startPos
    End Function
End Module

' The example displays the following output:
'       Fourth
'       Fifth

Metodi di estensione

GetMethodInfo(Delegate)

Ottiene un oggetto che rappresenta il metodo rappresentato dal delegato specificato.

Si applica a

Vedi anche