Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

string не содержит определение для toupper

Конечно, процесс помещения всех динамических обращений к методам в блоки

try/catch
довольно утомителен. Если вы тщательно следите за написанием кода и передачей параметров, тогда поступать так необязательно. Однако перехват исключений удобен, когда вы заранее не знаете, присутствует ли интересующий член в целевом типе.

Область использования ключевого слова dynamic

Вспомните, что неявно типизированные данные (объявленные с ключевым словом

var
) возможны только для локальных
переменных в области действия члена. Ключевое слово
var
никогда не может использоваться с возвращаемым значением, параметром или членом класса/структуры. Тем не менее, это не касается ключевого слова
dynamic
. Взгляните на следующее определение класса:

namespace DynamicKeyword

{

class VeryDynamicClass

{

// Динамическое поле.

private static dynamic _myDynamicField;

// Динамическое свойство.

public dynamic DynamicProperty { get; set; }

// Динамический тип возврата и динамический тип параметра.

public dynamic DynamicMethod(dynamic dynamicParam)

{

// Динамическая локальная переменная.

dynamic dynamicLocalVar = "Local variable";

int myInt = 10;

if (dynamicParam is int)

{

return dynamicLocalVar;

}

else

{

return myInt;

}

}

}

}

Теперь обращаться к открытым членам можно было бы ожидаемым образом; однако при работе с динамическими методами и свойствами нет полной уверенности в том, каким будет тип данных! По правде говоря, определение

VeryDynamicClass
может оказаться не особенно полезным в реальном приложении, но оно иллюстрирует область, где допускается применять ключевое слово
dynamic
.

Ограничения ключевого слова dynamic

Невзирая на то, что с использованием ключевого слова

dynamic
можно определять разнообразные сущности, с ним связаны некоторые ограничения. Хотя они не настолько впечатляющие, следует помнить, что элементы динамических данных при вызове метода не могут применять лямбда-выражения или анонимные методы С#. Например, показанный ниже код всегда будет давать в результате ошибки, даже если целевой метод на самом деле принимает параметр типа делегата, который в свою очередь принимает значение
string
и возвращает
void
:

dynamic a = GetDynamicObject;

// Ошибка! Методы на динамических данных не могут использовать

// лямбда-выражения!

a.Method(arg => Console.WriteLine(arg));

Чтобы

обойти упомянутое ограничение, понадобится работать с лежащим в основе делегатом напрямую, используя приемы из главы 12. Еще одно ограничение заключается в том, что динамический элемент данных не может воспринимать расширяющие методы (см. главу 11). К сожалению, сказанное касается также всех расширяющих методов из API-интерфейсов LINQ. Следовательно, переменная, объявленная с ключевым словом
dynamic
, имеет ограниченное применение в рамках LINQ to Objects и других технологий LINQ:

dynamic a = GetDynamicObject;

// Ошибка! Динамические данные не могут найти расширяющий метод Select!

var data = from d in a select d;

Практическое использование ключевого слова dynamic

С учетом того, что динамические данные не являются строго типизированными, не проверяются на этапе компиляции, не имеют возможности запускать средство IntelliSense и не могут быть целью запроса LINQ, совершенно корректно предположить, что применение ключевого слова

dynamic
лишь по причине его существования представляет собой плохую практику программирования.

Тем не менее, в редких обстоятельствах ключевое слово

dynamic
может радикально сократить объем вводимого вручную кода. В частности, при построении приложения .NET Core, в котором интенсивно используется позднее связывание (через рефлексию), ключевое слово
dynamic
может сэкономить время на наборе кода. Аналогично при разработке приложения .NET Core, которое должно взаимодействовать с унаследованными библиотеками СОМ (вроде тех, что входят в состав продуктов Microsoft Office), за счет использования ключевого слова
dynamic
можно значительно упростить кодовую базу. В качестве финального примера можно привести веб-приложения, построенные с применением ASP.NET Core: они часто используют тип
ViewBag
, к которому также допускается производить доступ в упрощенной манере с помощью ключевого слова
dynamic
.

На заметку! Взаимодействие с СОМ является строго парадигмой Windows и исключает межплатформенные возможности из вашего приложения.

Как с любым "сокращением", прежде чем его использовать, необходимо взвесить все "за" и "против". Применение ключевого слова

dynamic
— компромисс между краткостью кода и безопасностью к типам. В то время как C# в своей основе является строго типизированным языком, динамическое поведение можно задействовать (или нет) от вызова к вызову. Всегда помните, что использовать ключевое слово
dynamic
необязательно. Тот же самый конечный результат можно получить, написав альтернативный код вручную (правда, обычно намного большего объема).

Роль исполняющей среды динамического языка

Теперь, когда вы лучше понимаете сущность "динамических данных", давайте посмотрим, как их обрабатывать. Начиная с версии .NET 4.0, общеязыковая исполняющая среда (Common Language Runtime — CLR) получила дополняющую среду времени выполнения, которая называется исполняющей средой динамического языка (Dynamic Language Runtime — DLR). Концепция "динамической исполняющей среды" определенно не нова. На самом деле ее много лет используют такие языки программирования, как JavaScript, LISP, Ruby и Python. Выражаясь кратко, динамическая исполняющая среда предоставляет динамическим языкам возможность обнаруживать типы полностью во время выполнения без каких-либо проверок на этапе компиляции.

Поделиться с друзьями: