1. Темы лекции: Динамические типы.
Практическое задание: Динамические типы.
Тренер: Игорь Шкулипа, к.т.н.
Платформа .Net и язык программирования C#.
Занятие 14
2. http://www.slideshare.net/IgorShkulipa 2
Тип dynamic
Тип dynamic позволяет пропускать проверки типов во время компиляции операции,
в которых он применяется . Вместо этого эти операции разрешаются во время
выполнения. Тип dynamic упрощает доступ к API модели COM, например API
автоматизации Office, к динамическим API, например библиотекам IronPython, и
модели DOM HTML.
В большинстве случаев тип dynamic ведет себя так же, как object. Однако
операции, которые содержат выражения типа dynamic, не разрешаются, или
выполняется проверка типа компилятором. Компилятор пакует сведения об
операции, затем эти сведения используются для оценки операции во время
выполнения. Как часть процесса, переменные типа dynamic компилируются в
переменные типа object. Поэтому тип dynamic существует только во время
компиляции, но не во время выполнения.
class Program {
static void Main(string[] args) {
dynamic dyn = 1;
object obj = 1;
System.Console.WriteLine(dyn.GetType());
System.Console.WriteLine(obj.GetType());
}
}
System.Int32
System.Int32
3. http://www.slideshare.net/IgorShkulipa 3
Разница между object и dynamic
Чтобы понять различие между dyn и obj во время компиляции, можно
добавить следующие две строки между объявлениями и операторами
WriteLine в предыдущем примере.
dyn = dyn + 3;
obj = obj + 3;
• При попытке добавления целого числа или объекта в выражение
obj + 3 выводится ошибка компиляции.
• А для dyn + 3 нет сообщений об ошибках .
Выражение, содержащее dyn, не проверяется во время компиляции,
поскольку тип dyn задан как dynamic.
4. http://www.slideshare.net/IgorShkulipa 4
Использование dynamic
В объявлениях в качестве типа свойства, поля, индексатор, параметра,
возвращаемого значения, локальной переменной или ограничения типа.
class ExampleClass
{
static dynamic field;
dynamic prop { get; set; }
public dynamic exampleMethod(dynamic d)
{
dynamic local = "Local variable";
int two = 2;
if (d is int)
{
return local;
}
else
{
return two;
}
}
}
5. http://www.slideshare.net/IgorShkulipa 5
Использование dynamic
В преобразованиях явного типа в качестве типа целевого объекта преобразования.
static void convertToDynamic()
{
dynamic d;
int i = 20;
d = (dynamic)i;
Console.WriteLine(d);
string s = "Example string.";
d = (dynamic)s;
Console.WriteLine(d);
DateTime dt = DateTime.Today;
d = (dynamic)dt;
Console.WriteLine(d);
}
6. http://www.slideshare.net/IgorShkulipa 6
Использование dynamic
В любом контексте, где типы служат в качестве значений, например как типы с
правой стороны оператора is или as, или как аргумент в typeof в качестве части
сконструированного типа.
int i = 8;
dynamic d;
if (someVar is dynamic) { }
d = i as dynamic;
Console.WriteLine(typeof(List<dynamic>));
7. http://www.slideshare.net/IgorShkulipa 7
Пример dynamic
class Program
{
static void Main(string[] args)
{
dynamic ExcelApp = Type.GetTypeFromProgID("Excel.Application");
dynamic Excel = Activator.CreateInstance(ExcelApp);
Excel.Visible = true;
dynamic WorkBooks = Excel.Workbooks;
WorkBooks.Add(-4167);
Excel.Cells[1, 1].Value2 = "Hello, dynamic!";
Console.ReadKey();
}
}
Атрибут -4167 является счетчиком значения рабочей книги, который
применяется к объектам книги.
8. http://www.slideshare.net/IgorShkulipa 8
Как работает тип dynamic
Несмотря на то, что dynamic – это отдельный тип в языке C#, на уровне
CLR компилятор транслирует экземпляры dynamic в экземпляры
object с присоединенным к ним атрибутом.
class Class
{
public void Method (object o) {}
public void Method (dynamic d) {}
}
Этот код компилироваться не будет, так как компилятор выдаст ошибку
«Тип Class уже определяет метод Method с такими же типами
аргументов».
9. http://www.slideshare.net/IgorShkulipa 9
Ключевые слова var и dynamic
var указывает тип переменной, который должен быть присвоен типу
инициализатора периода компиляции.
dynamic подразумевает, что тип переменной является динамическим,
поддерживаемым в C# 4.0.
var улучшает статическую типизацию. Это ключевое слово помогает
компилятору корректно распознать тип переменной по точному типу,
возвращаемому инициализатором.
Ключевое слово dynamic обеспечивает полный уход от статической
типизации. При использовании в объявлении переменной оно
указывает компилятору вообще не обрабатывать тип переменной. Тип
должен быть таким, каким он окажется в период выполнения.
Другое различие между этими двумя ключевыми словами состоит в том,
что var может появляться только в объявлении локальной
переменной. Использовать var для определения свойства класса,
возвращаемого значения или параметра функции нельзя.
10. http://www.slideshare.net/IgorShkulipa 10
Динамические преобразования
Все типы неявно преобразуются в dynamic в соответствии со следующими
правилами:
• Существует неявное преобразование из любого ссылочного типа в тип
dynamic.
• Существует неявное упаковывающее преобразование из любого типа
значений в тип dynamic.
• Существует неявное преобразование идентичности из типа dynamic в
тип dynamic.
• Существует неявное преобразование идентичности из типа object в
тип dynamic.
• Существует неявное преобразование идентичности между
сконструированными типами, у которых обобщенные аргументы
отличаются только типами object и dynamic.
11. http://www.slideshare.net/IgorShkulipa 11
Динамическая перегрузка
public class StaticClass {
public static void PrintDynamic(double dbl, dynamic dyn) {
Console.WriteLine("void PrintDynamic(double dbl, dynamic dyn);");
}
public static void PrintDynamic(int i, string str) {
Console.WriteLine("void PrintDynamic(int i, string str);");
}
}
class Program {
static void Main(string[] args) {
dynamic d1 = "Hello, dynamic!";
dynamic d2 = new object();
StaticClass.PrintDynamic(1.2, d1);
StaticClass.PrintDynamic(1, d1);
StaticClass.PrintDynamic(2, d2);
Console.ReadKey();
}
}
void PrintDynamic(double dbl, dynamic dyn);
void PrintDynamic(int i, string str);
void PrintDynamic(double dbl, dynamic dyn);