Action<T1,T2,T3> Делегат

Определение

Инкапсулирует метод, который имеет три параметра и не возвращает значений.

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)

Параметры типа

T1

Тип первого параметра метода, инкапсулируемого данным делегатом.

Это контравариантный параметр типа. Это означает, что вы можете использовать любой из указанных типов или любой тип, являющийся менее производным. Дополнительные сведения о ковариантности и контрвариантности см. в статье Ковариантность и контрвариантность в универсальных шаблонах.
T2

Тип второго параметра метода, инкапсулируемого этим делегатом.

Это контравариантный параметр типа. Это означает, что вы можете использовать любой из указанных типов или любой тип, являющийся менее производным. Дополнительные сведения о ковариантности и контрвариантности см. в статье Ковариантность и контрвариантность в универсальных шаблонах.
T3

Тип третьего параметра метода, инкапсулируемого этим делегатом.

Это контравариантный параметр типа. Это означает, что вы можете использовать любой из указанных типов или любой тип, являющийся менее производным. Дополнительные сведения о ковариантности и контрвариантности см. в статье Ковариантность и контрвариантность в универсальных шаблонах.

Параметры

arg1
T1

Первый параметр метода, инкапсулируемого данным делегатом.

arg2
T2

Второй параметр метода, инкапсулируемого данным делегатом.

arg3
T3

Третий параметр метода, инкапсулируемого данным делегатом.

Комментарии

Делегат можно использовать для передачи Action<T1,T2,T3> метода в качестве параметра без явного объявления пользовательского делегата. Инкапсулированный метод должен соответствовать сигнатуре метода, определенной этим делегатом. Это означает, что инкапсулированный метод должен иметь три параметра, которые передаются ему по значению, и он не должен возвращать значение. (В C# метод должен возвращать void. В F# метод или функция должны возвращать единицу измерения. В Visual Basic он должен быть определен с помощью Subконструкции ...End Sub . Это также может быть метод, возвращающий значение, которое игнорируется.) Как правило, такой метод используется для выполнения операции.

Примечание

Для ссылки на метод, который имеет три параметра и возвращает значение, используйте вместо него универсальный Func<T1,T2,T3,TResult> делегат.

При использовании делегата Action<T1,T2,T3> не нужно явно определять делегат, который инкапсулирует метод с тремя параметрами. Например, следующий код явно объявляет делегат с именем StringCopy и назначает ссылку CopyStrings на метод его экземпляру делегата.

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] = string.Copy(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 Main()
      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
         Console.WriteLine(ordinal)
      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) = String.Copy(source(ctr))
      Next
   End Sub
End Module

В следующем примере этот код упрощается путем создания Action<T1,T2,T3> экземпляра делегата вместо явного определения нового делегата и назначения ему именованного метода.

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] = string.Copy(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 Main()
      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
         Console.WriteLine(ordinal)
      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) = String.Copy(source(ctr))
      Next
   End Sub
End Module

Делегат также можно использовать с анонимными методами Action<T1,T2,T3> в C#, как показано в следующем примере. (Общие сведения об анонимных методах см. в разделе Анонимные методы.)

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] = string.Copy(source[ctr]);
   }
}

Вы также можете назначить лямбда-выражение экземпляру Action<T1,T2,T3> делегата, как показано в следующем примере. (Общие сведения о лямбда-выражениях см. в разделе Лямбда-выражения (C#) или лямбда-выражения (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(ordinal == string.Empty ? "<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] = string.Copy(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 Main()
      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) = String.Copy(source(ctr))
      Next
      Return source.Length - startPos 
   End Function
End Module
' The example displays the following output:
'       Fourth
'       Fifth

Методы расширения

GetMethodInfo(Delegate)

Получает объект, представляющий метод, представленный указанным делегатом.

Применяется к

См. также раздел