Рейтинг - 0.0 (0)

Всем невероятный привет! smile С Вами, как всегда, wmysterio, и сегодня я расскажу очередную интересную информацию о C#. Из заголовка статьи, некоторые уже догадались о чём будет идти речь, но я решил поделится со всеми желающими этими возможностями.
Начну этот рассказ с динамических типов, вернее сказать типом. Его суть в том, что переменная в классе или структуре может иметь "плавающий" тип. Другими словами менять свой тип в ходе выполнения программы. Для знакомства с темами урока, давайте создадим новый проект консольного приложения. Для экспериментов создадим класс "DynamicClass" с пустым конструктором:
Код
using System;

namespace test {

  class Program {

  static void Main( string[] args ) {

  }

  }

  // Наш новый класс
  public class DynamicClass {

  public DynamicClass() { }
   
  }

}
Теперь нужно добавить новое слово в наш шарп-лексику - dynamic. Давайте добавим в Наш класс поле с именем "Field", и укажем в конструкторе, что оно по-умолчанию равно нулю:
Код
// Наш новый класс
public class DynamicClass {

  public dynamic Field; // Наше динамическое поле

  public DynamicClass() { Field = 0; }
   
}
Теперь делаем тесты в функции Main. Для начала сделаем вывод значения и тип экземпляра этого класса в консоли:
Код
class Program {

  static void Main( string[] args ) {

  DynamicClass dyn = new DynamicClass();
  Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );
  Console.ReadKey();

  }

}
В итоге мы получили это:
Код
0, type System.Int32
. Наш конструктор по-умолчанию сработал и полю Field был задан тип int со значением 0. Давайте делать дальше тесты. Теперь к экземпляру "dyn" присвоим значение, которое явно отличается от System.Int32, например строку и проверим результат:
Код
class Program {

  static void Main( string[] args ) {

  DynamicClass dyn = new DynamicClass();
  Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );

  dyn.Field = "Моя тестовая строка";
  Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );

  Console.ReadKey();

  }

}
Консоль нам вывела следующее:
Код
0, type System.Int32
Моя тестовая строка, type System.String
О, чудо! Это настоящая метаморфоза! Давайте зададим полю Field другой экземпляр класса DynamicClass и посмотрим что из этого получится:
Код
class Program {

  static void Main( string[] args ) {

  DynamicClass dyn = new DynamicClass();
  DynamicClass dyn2 = new DynamicClass();

  Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );

  dyn.Field = "Моя тестовая строка";
  Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );

  dyn.Field = dyn2; // присваиваем объект класса DynamicClass
  Console.WriteLine( dyn.Field + ", type " + dyn.Field.GetType() );

  Console.ReadKey();

  }

}
В итоге у нас консолька выведет:
Код
0, type System.Int32
Моя тестовая строка, type System.String
test.DynamicClass, type test.DynamicClass
На первый взгляд можно не понять каким образом так получилось, но объяснение лёгкое: поскольку нет конкретного(значимого) значения, C# выводит в его качестве имя типа, как от функции "GetType()". Ваши тесты могут показать немного другие значение, но не пугайтесь. Такое имя зависит от namespace, в котором был создан класс. Если Вы название проект не "test", то имя вашего DynamicClass будет иметь вид: ВАШ_НЕЙМСПЕЙС.DynamicClass.
Как и в других хороших возможностях, существует такое "Но". Здесь без исключения. Но, с таким подходом нужно быть очень аккуратным, и это в первую очередь связано с использованием методов, полей и свойств динамического типа. Если Вы набирали текст руками, то заметили, что при вводе "dyn.Field." далее не было подсказок какие методы есть в следующей цепочке. Это не баг, а так устроен "подсветчик кода". Связано это с тем, что компилятор не знает каким типом может быть поле в процессе выполнения программы. По-этому нужно тщательно проверять программу на ввод корректных данных и уже потом вызывать метод. Метод, конечно, нужно писать по-памяти.

Следующим шагом будет разбор анонимных типов. Что-же это такое? Анонимные типы позволяют делать экземпляры одноразовых классов на ходу, в процессе написания кода. Естественно мы можем только догадываться какой тип нам сгенерирует компилятор, по-этому нам нужно где-то хранить результат. Для этого существует ключевое слово var. Это своего рода универсальный тип, который в зависимости от переданного ему значения образует его тип. Для проверки результатов, очистим метод Main и напишем несколько примеров с выводом типа и значения:
Код
class Program {

  static void Main( string[] args ) {

  var anonym1 = 0;
  var anonym2 = "анонимный тип";

  Console.WriteLine( anonym1 + ", type " + anonym1.GetType() );
  Console.WriteLine( anonym2 + ", type " + anonym2.GetType() );

  Console.ReadKey();

  }

}
Наша консоль покажет такой результат:
Код
0, type System.Int32
анонимный тип, type System.String
В таком виде ключевое слово var следует воспринимать как универсальный тип и о никакой анонимности не может быть и речи. Это слово очень помогает в скорости набора программы, поскольку в место написания какого-то километрового названия мы ограничиваемся тремя буквами(видимо, от слова Variable).
Поскольку мы рассматривает тему анонимности, то думаю, пришло время рассмотреть способ их создания. Самый простой вариант такой:
Код
var realAnonym = new {
  Name = "Василий",
  Age = 23,
  LoveColor = ConsoleColor.White
};
Практически создаётся так же, как и обычный класс или структура, но без указания типа. Теперь наша переменная "realAnonym" будет иметь в своём арсенале три свойства, которые мы указали в коде: Name, Age, LoveColor. Давайте проверим в нашей консоли какие типы были заданы нашим свойствам и какой тип образовался для нашего анонима:
Код
static void Main( string[] args ) {

  var realAnonym = new {
  Name = "Василий",
  Age = 23,
  LoveColor = ConsoleColor.White
  };

  Console.WriteLine( realAnonym.Name + ", type " + realAnonym.Name.GetType() );
  Console.WriteLine( realAnonym.Age + ", type " + realAnonym.Age.GetType() );
  Console.WriteLine( realAnonym.LoveColor + ", type " + realAnonym.LoveColor.GetType() );
  Console.WriteLine( realAnonym + ", type " + realAnonym.GetType() );

  Console.ReadKey();

  }

}
У меня консоль получила следующие данные:
Код
Василий, type System.String
23, type System.Int32
White, type System.ConsoleColor
{ Name = Василий, Age = 23, LoveColor = White }, type <>f_AnonymousType0`3[System.String,System.Int32,System.ConsoleColor]
Как видим, свойтва экземпляра были того типа, что и значение, а вот с типом этого экземпляра что-то не так smile Если бы мы обявили так:
Код
<>f_AnonymousType0`3[System.String,System.Int32,System.ConsoleColor] realAnonym = new {
  Name = "Василий",
  Age = 23,
  LoveColor = ConsoleColor.White
};
То естественно нам компилятор упрекнул бы в плохом оформлении кода smile В этом нам и помог var, который в примере уже выступает как анонимный тип и позволяет работать с тем экземпляром.
Слово var используется только в локальном контексте. Другими словами мы не можем сделать его типом свойства или поля класса, а используется он исключительно внутри методов, свойств и конструкторов/деструкторов. Но это не значит, что мы не можем использовать анонимные типы в не функций. Для самостоятельной работы попробуйте создать анонимный тип в dynamic поле и увидите wink

Расскажу ещё несколько слов о анонимных типах, а точнее где они часто используются. В нашем примере нет необходимости в таких типах, но при разработке серьёзных программ они часто используются. В следующих уроках я дам Вам более детальный пример, а на этом, пожалуй, всё. С вами был и есть - wmysterio. Бай.

Теги: Анонимные и динамические типы в c#
Вход на сайт

Поиск
Категории раздела
Мини-чат
Пожалуйста, все вопросы по скриптингу задавать на форуме!
Наш опрос
Как Вы узнали о сайте?
Всего ответов: 6
Активность на сайте
Пожертвования
Кошельки WebMoney:
U859420971000
R407741810602
Z331072372430
E314272616890
Друзья сайта
Полезные ресурсы
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Сегодня нас посетили:
Реклама