Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 231 232 233 234 235 236 237 238 239 ... 642

...

}

Делегаты могут также "указывать" на методы, которые содержат любое количество параметров out и ref (а также параметры типа массивов, помеченные с помощью ключевого слова params). Пусть имеется следующий тип делегата:

public delegate string MyOtherDelegate(out bool a, ref bool b, int c);

Сигнатура метода Invoke() выглядит вполне ожидаемо.

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

// Это лишь псевдокод!

public sealed class <i>ИмяДелегата</i> : System.MulticastDelegate

{

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

  public <i>возвращаемоеЗначениеДелегата</i>

      Invoke(<i>всеВходныеRefиOutПараметрыДелегата</i>);

}

Базовые классы System.MulticastDelegate и System.Delegate

Итак, когда вы строите тип с применением ключевого слова delegate, то неявно объявляете тип класса, производного от System.MulticastDelegate. Данный класс предоставляет своим наследникам доступ к списку, который содержит адреса методов, поддерживаемых типом делегата, а также несколько дополнительных методов (и перегруженных операций) для взаимодействия со списком вызовов. Ниже приведены избранные методы класса System.MulticastDelegate:

public abstract class MulticastDelegate : Delegate

{

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

<b>  // Возвращает список методов, на которые &quot;указывает&quot; делегат.</b>

  public sealed override Delegate[] GetInvocationList();

<b>  // Перегруженные операции.</b>

  public static bool operator ==

    (MulticastDelegate d1, MulticastDelegate d2);

  public static bool operator !=

    (MulticastDelegate d1, MulticastDelegate d2);

<b>  // Используются внутренне для управления списком методов,</b>

<b>  // поддерживаемых делегатом.</b>

  private IntPtr _invocationCount;

  private object _invocationList;

}

Класс System.MulticastDelegate получает дополнительную функциональность от своего родительского класса System.Delegate. Вот фрагмент его определения:

public abstract class Delegate : ICloneable, ISerializable

{

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

<b>  // Методы для взаимодействия со списком функций.</b>

  public static Delegate Combine(params Delegate[] delegates);

  public static Delegate Combine(Delegate a, Delegate b);

  public static Delegate Remove(

    Delegate source, Delegate value);

  public static Delegate RemoveAll(

    Delegate source, Delegate value);

<b>  // Перегруженные операции.</b>

  public static bool operator ==(Delegate d1, Delegate d2);

  public static bool operator !=(Delegate d1, Delegate d2);

<b>  // Свойства, открывающие доступ к цели делегата.</b>

  public MethodInfo Method { get; }

  public object Target { get; }

}

Имейте в виду, что вы никогда не сможете напрямую наследовать от таких базовых классов в своем коде (попытка наследования приводит к ошибке на этапе компиляции). Тем не менее, когда вы используете ключевое слово delegate, то тем самым неявно создаете класс, который "является" MulticastDelegate. В табл. 12.1 описаны основные члены, общие для всех типов делегатов.

Пример простейшего делегата

На первый взгляд делегаты могут показаться несколько запутанными. Рассмотрим для начала простой проект консольного приложения (по имени SimpleDelegate), в котором применяется определенный ранее тип делегата BinaryOp. Ниже показан полный код с последующим анализом:

// SimpleMath.cs

namespace SimpleDelegate

{

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

  // Этот класс содержит методы, на которые

  // будет указывать BinaryOp.

  public class SimpleMath

  {

    public static int Add(int x, int y) =&gt; x + y;

    public static int Subtract(int x, int y) =&gt; x - y;

  }

}

// Program.cs

using System;

using SimpleDelegate;

Console.WriteLine(&quot;***** Simple Delegate Example *****n&quot;);

<b>// Создать объект делегата BinaryOp, который</b>

<b>// &quot;указывает&quot; на SimpleMath.Add().</b>

1 ... 231 232 233 234 235 236 237 238 239 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий