Console.WriteLine("t is of type: {0}", t.GetType());
}
Вот вывод:
t is of type: System.String
t is of type: System.Boolean
t is of type: System.Collections.Generic.List`1[System.Int32]
Имейте в виду, что приведенный выше код успешно скомпилировался и дал бы идентичный результат, если бы переменная t
System.Object. Однако, как вскоре будет показано, ключевое слово dynamic предлагает много дополнительных возможностей.Вызов членов на динамически объявленных данных
Учитывая то, что динамическая переменная способна принимать идентичность любого типа на лету (подобно переменной типа System.Object
Но (и это очень важное "но") допустимость указываемых членов компилятор проверять не будет! Вспомните, что в отличие от переменной, определенной с типом System.Object
static void InvokeMembersOnDynamicData()
{
dynamic textData1 = "Hello";
Console.WriteLine(textData1.ToUpper());
// Здесь можно было бы ожидать ошибки на этапе компиляции!
// Однако все компилируется нормально.
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'
Другое очевидное отличие между обращением к членам динамических и строго типизированных данных связано с тем, что когда к элементу динамических данных применяется операция точки, ожидаемое средство IntelliSense среды Visual Studio не активизируется. Взамен IDE-среда позволит вводить любое имя члена, какое только может прийти вам на ум.
Отсутствие возможности доступа к средству IntelliSense для динамических данных должно быть понятным. Тем не менее, как вы наверняка помните, это означает необходимость соблюдения предельной аккуратности при наборе кода C# для таких элементов данных. Любая опечатка или символ в неправильном регистре внутри имени члена приведет к ошибке времени выполнения, в частности к генерации исключения типа RuntimeBinderException
Класс RuntimeBinderException
toupper() и Foo()). Та же самая ошибка будет инициирована, если для члена, который существует, указаны некорректные данные параметров.Поскольку динамические данные настолько изменчивы, любые обращения к членам переменной, объявленной с ключевым словом dynamic
try/catch для элегантной обработки ошибок:static void InvokeMembersOnDynamicData()