Ответ
dynamic — это тип, который включает проверку типов не во время компиляции, а во время выполнения (runtime). Объявленные как dynamic сущности пропускают статическую проверку типов компилятором C#. Это мощный инструмент, который следует использовать осознанно.
Основные сценарии использования:
- Работа с COM-объектами (например, Office Interop): Упрощает API, который часто возвращает
object. - Использование динамических языков через DLR (Dynamic Language Runtime): Взаимодействие с кодом на IronPython или IronRuby.
- Работа с JSON/XML данными неизвестной структуры (хотя сейчас предпочтительнее
System.Text.Jsonили Newtonsoft.Json). - Создание динамических объектов с помощью
ExpandoObject.
Пример:
dynamic dynamicVariable = "Это строка";
Console.WriteLine(dynamicVariable.Length); // Работает, у string есть Length
Console.WriteLine(dynamicVariable.ToUpper()); // Работает
dynamicVariable = 42;
Console.WriteLine(dynamicVariable + 10); // Работает, сложение чисел
// Console.WriteLine(dynamicVariable.ToUpper()); // Выбросит RuntimeBinderException!
Важные особенности и предостережения:
- Производительность: Операции с
dynamicмедленнее из-за разрешения вызовов в рантайме. - Безопасность типов: Ошибки, которые компилятор поймал бы статически (например, вызов несуществующего метода), проявятся только во время выполнения как
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException. - IntelliSense: Подсказки по членам объекта в IDE отсутствуют.
- Преобразования: Компилятор неявно преобразует
dynamicв любой другой тип.dynamic d = 5; int i = d; // OK, преобразование dynamic -> int в runtime string s = d; // RuntimeBinderException, если значение не строковое
Правило: Используйте dynamic только когда выгода от упрощения кода перевешивает потерю безопасности типов и производительности, и когда статически типизированная альтернатива (интерфейсы, обобщенные методы) неприменима.