Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
static void InvokeMembersOnDynamicData()
{
dynamic textData1 = "Hello";
Console.WriteLine(textData1.ToUpper());
<b> // Здесь можно было бы ожидать ошибки на этапе компиляции!</b>
<b> // Однако все компилируется нормально.</b>
Console.WriteLine(textData1.toupper());
Console.WriteLine(textData1.Foo(10, "ee", DateTime.Now));
}
Обратите внимание, что во втором вызове
WriteLine()
toupper()
ToUpper()
textData1
string
string
Foo()
int
string
DataTime
Тем не менее, компилятор C# ни о каких ошибках не сообщает. Однако если вызвать метод
InvokeMembeгsOnDynamicData()
Unhandled Exception : Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
'string' does not contain a definition for 'toupper'
Необработанное исключение: Microsoft.CSharp.RuntimeBinder.
RuntimeBinderException: string не содержит определения для toupper
Другое очевидное отличие между обращением к членам динамических и строго типизированных данных связано с тем, что когда к элементу динамических данных применяется операция точки, ожидаемое средство IntelliSense среды Visual Studio не активизируется. Взамен IDE-среда позволит вводить любое имя члена, какое только может прийти вам на ум.
Отсутствие возможности доступа к средству IntelliSense для динамических данных должно быть понятным. Тем не менее, как вы наверняка помните, это означает необходимость соблюдения предельной аккуратности при наборе кода C# для таких элементов данных. Любая опечатка или символ в неправильном регистре внутри имени члена приведет к ошибке времени выполнения, в частности к генерации исключения типа
RuntimeBinderException
Класс
RuntimeBinderException
toupper()
Foo()
Поскольку динамические данные настолько изменчивы, любые обращения к членам переменной, объявленной с ключевым словом
dynamic
try/catch
static void InvokeMembersOnDynamicData()
{
dynamic textData1 = "Hello";
try
{
Console.WriteLine(textData1.ToUpper());
Console.WriteLine(textData1.toupper());
Console.WriteLine(textData1.Foo(10, "ee", DateTime.Now));
}
catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ex)
{
Console.WriteLine(ex.Message);
}
}
Если вызвать метод
InvokeMembersOnDynamicData()
ToUpper()
HELLO
'string' does not contain a definition for 'toupper'
<i>string не содержит определение для toupper</i>
Конечно, процесс помещения всех динамических обращений к методам в блоки
try/catch
Область использования ключевого слова dynamic
Вспомните, что неявно типизированные данные (объявленные с ключевым словом
var
var
dynamic
namespace DynamicKeyword
{
class VeryDynamicClass
{
<b> // Динамическое поле.</b>
private static dynamic _myDynamicField;
<b> // Динамическое свойство.</b>
public dynamic DynamicProperty { get; set; }
<b> // Динамический тип возврата и динамический тип параметра.</b>
public dynamic DynamicMethod(dynamic dynamicParam)
{
<b> // Динамическая локальная переменная.</b>