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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 149 150 151 152 153 154 155 156 157 ... 407
class="code">  // быть перемещен или уничтожен сборщиком мусора.

  fixed (int* p = &pt.x)

  {

    // Использовать здесь переменную int*!

  }

  // Указатель pt теперь не закреплен и готов

  // к сборке мусора после завершения метода.

  Console.WriteLine ("Point is: {0}", pt);

}

Выражаясь кратко, ключевое слово fixed позволяет строить оператор, который фиксирует ссылочную переменную в памяти, чтобы ее адрес оставался постоянным на протяжении работы оператора (или блока операторов). Каждый раз, когда вы взаимодействуете со ссылочным типом из контекста небезопасного кода, закрепление ссылки обязательно. 

Ключевое слово sizeof

Последнее ключевое слово С#, связанное с небезопасным кодом — sizeof. Как и в C++, ключевое слово sizeof в C# используется для получения размера в байтах встроенного типа данных, но не специального типа, разве только в небезопасном контексте. Например, показанный ниже метод не нуждается в объявлении "небезопасным", т.к. все аргументы ключевого слова sizeof относятся к встроенным типам:

static void UseSizeOfOperator()

{

  Console.WriteLine("The size of short is {0}.", sizeof(short));

  Console.WriteLine("The size of int is {0}.", sizeof(int));

  Console.WriteLine("The size of long is {0}.", sizeof(long));

}

Тем не менее, если вы хотите получить размер специальной структуры Point, то метод UseSizeOfOperator() придется модифицировать (обратите внимание на добавление ключевого слова unsafe):

unsafe static void UseSizeOfOperator()

{

  ...

  unsafe {

    Console.WriteLine("The size of Point is {0}.", sizeof(Point));

  }

}

Итак, обзор нескольких более сложных средств языка программирования C# завершен. Напоследок снова необходимо отметить, что в большинстве проектов .NET эти средства могут вообще не понадобиться (особенно указатели). Тем не менее, как будет показано в последующих главах, некоторые средства действительно полезны (и даже обязательны) при работе с API-интерфейсами LINQ, в частности расширяющие методы и анонимные типы. 

Резюме

Целью главы было углубление знаний языка программирования С#. Первым делом мы исследовали разнообразные более сложные конструкции в типах (индексаторные методы, перегруженные операции и специальные процедуры преобразования).

Затем мы рассмотрели роль расширяющих методов и анонимных типов. Как вы увидите в главе 13, эти средства удобны при работе с API-интерфейсами LINQ (хотя при желании их можно применять в коде повсеместно). Вспомните, что анонимные методы позволяют быстро моделировать "форму" типа, в то время как расширяющие методы дают возможность добавлять новую функциональность к типам без необходимости в определении подклассов.

Финальная часть главы была посвящена небольшому набору менее известных ключевых слов (sizeof, unsafe и т.п.); наряду с ними рассматривалась работа с низкоуровневыми типами указателей. Как было установлено в процессе исследования типов указателей, в большинстве приложений C# их никогда не придется использовать.

Глава 12

Делегаты, события и лямбда-выражения

Вплоть до настоящего момента в большинстве разработанных приложений к операторам верхнего уровня внутри файла Program.cs добавлялись разнообразные порции кода, тем или иным способом отправляющие запросы к заданному объекту. Однако многие приложения требуют, чтобы объект имел возможность обращаться обратно к сущности, которая его создала, используя механизм обратного вызова. Хотя механизмы обратного вызова могут применяться в любом приложении, они особенно важны в графических пользовательских интерфейсах, где элементы управления (такие как кнопки) нуждаются в вызове внешних методов при надлежащих обстоятельствах (когда произведен щелчок на кнопке, курсор мыши наведен на поверхность кнопки и т.д.).

В рамках платформы .NET Core предпочтительным средством определения и реагирования на обратные вызовы в приложении является тип делегата. По существу тип делегата .NET Core — это безопасный в отношении типов объект, "указывающий" на метод или список методов, которые могут быть вызваны позднее. Тем не менее, в отличие от традиционного указателя на функцию C++ делегаты представляют собой классы, которые обладают встроенной поддержкой группового и асинхронного вызова методов.

На заметку! В предшествующих версиях .NET делегаты обеспечивали вызов асинхронных методов с помощью BeginInvoke()/EndInvoke(). Хотя компилятор по-прежнему генерирует методы BeginInvoke()/EndInvoke(), в .NET Core они не поддерживаются. Причина в том, что шаблон с IAsyncResult и BeginInvoke()/EndInvoke(), используемый делегатами, был заменен асинхронным шаблоном на основе задач. Асинхронное выполнение подробно обсуждается в главе 15.

В текущей главе вы узнаете, каким образом создавать и манипулировать типами делегатов, а также использовать ключевое слово event языка С#, которое облегчает работу с типами делегатов. По ходу дела вы также изучите несколько языковых средств С#, ориентированных на делегаты и события, в том числе анонимные методы и групповые преобразования методов.

Глава завершается исследованием лямбда-выражений. С помощью лямбда-операции C# (=>) можно указывать блок операторов кода (и подлежащие передаче им параметры) везде, где требуется строго типизированный делегат. Как будет показано, лямбда-выражение — не более чем замаскированный анонимный метод и является упрощенным подходом к работе с делегатами. Вдобавок та же самая операция (в .NEТ Framework 4.6 и последующих версиях) может применяться для реализации метода или свойства, содержащего единственный оператор, посредством лаконичного синтаксиса.

Понятие типа делегата

Прежде чем формально определить делегаты, давайте ненадолго оглянемся назад. Исторически сложилось так, что в API-интерфейсе Windows часто использовались указатели на функции в стиле С для создания сущностей под названием функции обратного вызова или просто обратные вызовы. С помощью обратных вызовов программисты могли конфигурировать одну функцию так, чтобы она обращалась к другой функции в приложении (т.е. делала обратный вызов). С применением такого подхода разработчики Windows-приложений имели возможность обрабатывать щелчки на кнопках, перемещение курсора мыши, выбор пунктов меню и общие двусторонние коммуникации между двумя сущностями в памяти.

В .NET и .NET Core обратные вызовы выполняются в безопасной в отношении типов объектно-ориентированной манере с использованием делегатов. Делегат — это безопасный в отношении типов объект, указывающий на другой метод или возможно на список методов приложения, которые могут быть вызваны в более позднее время.

В частности, делегат поддерживает три важных порции информации:

адрес метода, вызовы которого он делает:

аргументы (если есть) вызываемого метода:

возвращаемое значение (если есть) вызываемого метода.

На заметку! Делегаты .NET Core могут указывать либо на статические методы, либо на методы экземпляра.

После того как делегат создан и снабжен необходимой информацией, он может во время выполнения динамически вызывать метод или методы, на которые

1 ... 149 150 151 152 153 154 155 156 157 ... 407
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен бесплатно.

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