> For the complete documentation index, see [llms.txt](https://lessons.sannybuilder.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lessons.sannybuilder.com/00300/00100/000169.-anonimnye-i-dinamicheskie-tipy-v-c.md).

# 000169. Анонимные и динамические типы в c\#

Анонимные и динамические типы в c#||wmysterio|wmysterio|<wmysterio@yandex.ru>|/||Всем невероятный привет! ![smile](http://s49.ucoz.net/sm/15/smile.gif) С Вами, как всегда, wmysterio, и сегодня я расскажу очередную интересную информацию о C#. Из заголовка статьи, некоторые уже догадались о чём будет идти речь, но я решил поделится со всеми желающими этими возможностями.\
Начну этот рассказ с динамических типов, вернее сказать типом. Его суть в том, что переменная в классе или структуре может иметь "плавающий" тип. Другими словами менять свой тип в ходе выполнения программы. Для знакомства с темами урока, давайте создадим новый проект консольного приложения. Для экспериментов создадим класс "DynamicClass" с пустым конструктором:

Кодusing System;\
\
namespace test {\
\
&#x20; class Program {\
\
&#x20; static void Main( string\[] args ) {\
\
&#x20; }\
\
&#x20; }\
\
&#x20; // Наш новый класс\
&#x20; public class DynamicClass {\
\
&#x20; public DynamicClass() { }\
&#x20;  \
&#x20; }\
\
}Теперь нужно добавить новое слово в наш шарп-лексику - **dynamic**. Давайте добавим в Наш класс поле с именем "Field", и укажем в конструкторе, что оно по-умолчанию равно нулю:Код// Наш новый класс\
public class DynamicClass {\
\
&#x20; public dynamic Field; // Наше динамическое поле\
\
&#x20; public DynamicClass() { Field = 0; }\
&#x20;  \
}Теперь делаем тесты в функции Main. Для начала сделаем вывод значения и тип экземпляра этого класса в консоли:Кодclass Program {\
\
&#x20; static void Main( string\[] args ) {\
\
&#x20; DynamicClass dyn = new DynamicClass();\
&#x20; Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );\
&#x20; Console.ReadKey();\
\
&#x20; }\
\
}В итоге мы получили это:Код0, type System.Int32. Наш конструктор по-умолчанию сработал и полю Field был задан тип int со значением 0. Давайте делать дальше тесты. Теперь к экземпляру "dyn" присвоим значение, которое явно отличается от System.Int32, например строку и проверим результат:Кодclass Program {\
\
&#x20; static void Main( string\[] args ) {\
\
&#x20; DynamicClass dyn = new DynamicClass();\
&#x20; Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );\
\
&#x20; dyn.Field = "Моя тестовая строка";\
&#x20; Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );\
\
&#x20; Console.ReadKey();\
\
&#x20; }\
\
}Консоль нам вывела следующее:Код0, type System.Int32\
Моя тестовая строка, type System.StringО, чудо! Это настоящая метаморфоза! Давайте зададим полю Field другой экземпляр класса DynamicClass и посмотрим что из этого получится:Кодclass Program {\
\
&#x20; static void Main( string\[] args ) {\
\
&#x20; DynamicClass dyn = new DynamicClass();\
&#x20; DynamicClass dyn2 = new DynamicClass();\
\
&#x20; Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );\
\
&#x20; dyn.Field = "Моя тестовая строка";\
&#x20; Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );\
\
&#x20; dyn.Field = dyn2; // присваиваем объект класса DynamicClass\
&#x20; Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );\
\
&#x20; Console.ReadKey();\
\
&#x20; }\
\
}В итоге у нас консолька выведет:Код0, type System.Int32\
Моя тестовая строка, type System.String\
test.DynamicClass, type test.DynamicClassНа первый взгляд можно не понять каким образом так получилось, но объяснение лёгкое: поскольку нет конкретного(значимого) значения, C# выводит в его качестве имя типа, как от функции "GetType()". Ваши тесты могут показать немного другие значение, но не пугайтесь. Такое имя зависит от namespace, в котором был создан класс. Если Вы название проект не "test", то имя вашего DynamicClass будет иметь вид: **ВАШ\_НЕЙМСПЕЙС.DynamicClass**.\
Как и в других хороших возможностях, существует такое "Но". Здесь без исключения. Но, с таким подходом нужно быть очень аккуратным, и это в первую очередь связано с использованием методов, полей и свойств динамического типа. Если Вы набирали текст руками, то заметили, что при вводе "dyn.Field." далее не было подсказок какие методы есть в следующей цепочке. Это не баг, а так устроен "подсветчик кода". Связано это с тем, что компилятор не знает каким типом может быть поле в процессе выполнения программы. По-этому нужно тщательно проверять программу на ввод корректных данных и уже потом вызывать метод. Метод, конечно, нужно писать по-памяти.\
\
Следующим шагом будет разбор анонимных типов. Что-же это такое? Анонимные типы позволяют делать экземпляры одноразовых классов на ходу, в процессе написания кода. Естественно мы можем только догадываться какой тип нам сгенерирует компилятор, по-этому нам нужно где-то хранить результат. Для этого существует ключевое слово **var**. Это своего рода универсальный тип, который в зависимости от переданного ему значения образует его тип. Для проверки результатов, очистим метод Main и напишем несколько примеров с выводом типа и значения:Кодclass Program {\
\
&#x20; static void Main( string\[] args ) {\
\
&#x20; var anonym1 = 0;\
&#x20; var anonym2 = "анонимный тип";\
\
&#x20; Console.WriteLine( anonym1 + ", type " + anonym1.GetType() );\
&#x20; Console.WriteLine( anonym2 + ", type " + anonym2.GetType() );\
\
&#x20; Console.ReadKey();\
\
&#x20; }\
\
}Наша консоль покажет такой результат:Код0, type System.Int32\
анонимный тип, type System.StringВ таком виде ключевое слово var следует воспринимать как универсальный тип и о никакой анонимности не может быть и речи. Это слово очень помогает в скорости набора программы, поскольку в место написания какого-то километрового названия мы ограничиваемся тремя буквами(видимо, от слова Variable).\
Поскольку мы рассматривает тему анонимности, то думаю, пришло время рассмотреть способ их создания. Самый простой вариант такой:Кодvar realAnonym = new {\
&#x20; Name = "Василий",\
&#x20; Age = 23,\
&#x20; LoveColor = ConsoleColor.White\
};Практически создаётся так же, как и обычный класс или структура, но без указания типа. Теперь наша переменная "realAnonym" будет иметь в своём арсенале три свойства, которые мы указали в коде: **Name**, **Age**, **LoveColor**. Давайте проверим в нашей консоли какие типы были заданы нашим свойствам и какой тип образовался для нашего анонима:Кодstatic void Main( string\[] args ) {\
\
&#x20; var realAnonym = new {\
&#x20; Name = "Василий",\
&#x20; Age = 23,\
&#x20; LoveColor = ConsoleColor.White\
&#x20; };\
\
&#x20; Console.WriteLine( realAnonym.Name + ", type " + realAnonym.Name.GetType() );\
&#x20; Console.WriteLine( realAnonym.Age + ", type " + realAnonym.Age.GetType() );\
&#x20; Console.WriteLine( realAnonym.LoveColor + ", type " + realAnonym.LoveColor.GetType() );\
&#x20; Console.WriteLine( realAnonym + ", type " + realAnonym.GetType() );\
\
&#x20; Console.ReadKey();\
\
&#x20; }\
\
}У меня консоль получила следующие данные:КодВасилий, type System.String\
23, type System.Int32\
White, type System.ConsoleColor\
{ Name = Василий, Age = 23, LoveColor = White }, type <>f\_AnonymousType0`3&#91;System.String,System.Int32,System.ConsoleColor]<!--/uzc--></div></div><!--/uzcode-->Как видим, свойтва экземпляра были того типа, что и значение, а вот с типом этого экземпляра что-то не так <img src="http://s49.ucoz.net/sm/15/smile.gif" border="0" align="absmiddle" alt="smile" /> Если бы мы обявили так:<!--uzcode--><div class="bbCodeBlock"><div class="bbCodeName" style="padding-left:5px;font-weight:bold;font-size:7pt">Код</div><div class="codeMessage" style="border:1px inset;max-height:200px;overflow:auto;height:expression(this.scrollHeight<5?this.style.height:scrollHeight>200?'200px':''+(this.scrollHeight+5)+'px');"><!--uzc-->&lt;>f_AnonymousType0`3\[System.String,System.Int32,System.ConsoleColor] realAnonym = new {\
&#x20; Name = "Василий",\
&#x20; Age = 23,\
&#x20; LoveColor = ConsoleColor.White\
};То естественно нам компилятор упрекнул бы в плохом оформлении кода ![smile](http://s49.ucoz.net/sm/15/smile.gif) В этом нам и помог var, который в примере уже выступает как анонимный тип и позволяет работать с тем экземпляром.\
Слово var используется только в локальном контексте. Другими словами мы не можем сделать его типом свойства или поля класса, а используется он исключительно внутри методов, свойств и конструкторов/деструкторов. Но это не значит, что мы не можем использовать анонимные типы в не функций. Для самостоятельной работы попробуйте создать анонимный тип в dynamic поле и увидите ![wink](http://s49.ucoz.net/sm/15/wink.gif)\
\
Расскажу ещё несколько слов о анонимных типах, а точнее где они часто используются. В нашем примере нет необходимости в таких типах, но при разработке серьёзных программ они часто используются. В следующих уроках я дам Вам более детальный пример, а на этом, пожалуй, всё. С вами был и есть - wmysterio. Бай.|1264|1|0||anonimnye\_i\_dinamicheskie\_tipy\_v\_c|1425501811
