Compartilhar via


Action<T1,T2,T3> Delegar

Definição

Encapsula um método que tem três parâmetros e não retorna um valor.

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)

Parâmetros de tipo

T1

O tipo do primeiro parâmetro do método encapsulado por esse delegado.

Este parâmetro de tipo é contravariante. Isso significa que é possível usar o tipo especificado ou qualquer tipo menos derivado. Para obter mais informações sobre covariância e contravariância, consulte Covariância e contravariância em genéricos.
T2

O tipo do segundo parâmetro do método encapsulado por esse delegado.

Este parâmetro de tipo é contravariante. Isso significa que é possível usar o tipo especificado ou qualquer tipo menos derivado. Para obter mais informações sobre covariância e contravariância, consulte Covariância e contravariância em genéricos.
T3

O tipo do terceiro parâmetro do método encapsulado por esse delegado.

Este parâmetro de tipo é contravariante. Isso significa que é possível usar o tipo especificado ou qualquer tipo menos derivado. Para obter mais informações sobre covariância e contravariância, consulte Covariância e contravariância em genéricos.

Parâmetros

arg1
T1

O primeiro parâmetro do método que esse delegado encapsula.

arg2
T2

O segundo parâmetro do método que esse delegado encapsula.

arg3
T3

O terceiro parâmetro do método encapsulado por esse delegado.

Comentários

Você pode usar o delegado Action<T1,T2,T3> para passar um método como um parâmetro sem declarar explicitamente um delegado personalizado. O método encapsulado deve corresponder à assinatura do método definida por esse delegado. Isso significa que o método encapsulado deve ter três parâmetros que são todos passados para ele por valor e não deve retornar um valor. (Em C#, o método deve retornar void. Em F#, o método ou função deve retornar a unidade. No Visual Basic, ele deve ser definido pelo constructo Sub...End Sub. Ele também pode ser um método que retorna um valor ignorado.) Normalmente, esse método é usado para executar uma operação.

Nota

Para fazer referência a um método que tem três parâmetros e retorna um valor, use o delegado de Func<T1,T2,T3,TResult> genérico.

Ao usar o delegado Action<T1,T2,T3>, você não precisa definir explicitamente um delegado que encapsula um método com três parâmetros. Por exemplo, o código a seguir declara explicitamente um delegado chamado StringCopy e atribui uma referência ao método CopyStrings à instância delegada.

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

O exemplo a seguir simplifica esse código instanciando o delegado Action<T1,T2,T3> em vez de definir explicitamente um novo delegado e atribuir um método nomeado a ele.

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

Você também pode usar o delegado Action<T1,T2,T3> com métodos anônimos em C#, como ilustra o exemplo a seguir. (Para obter uma introdução aos métodos anônimos, consulte Métodos Anônimos.)

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

Você também pode atribuir uma expressão lambda a uma instância de delegado Action<T1,T2,T3>, como ilustra o exemplo a seguir. (Para obter uma introdução às expressões lambda, consulte expressões Lambda (C#) ou expressões 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

Métodos de Extensão

GetMethodInfo(Delegate)

Obtém um objeto que representa o método representado pelo delegado especificado.

Aplica-se a

Confira também