Подтвердить что ты не робот

Анонимный тип и динамический тип

Каковы реальные различия между анонимным типом (var) в С# 3.0 и динамическим типом (динамическим), который приходит в С# 4.0?

4b9b3361

Ответ 1

Анонимный тип - это реальный, сгенерированный компилятором тип, созданный для вас. Хорошо, что компилятор может повторно использовать этот тип позже для других операций, которые требуют его, поскольку это POCO.

Мое понимание динамических типов заключается в том, что они являются поздними, что означает, что CLR (или DLR) будет оценивать объект во время выполнения, а затем использовать утиную типизацию, чтобы разрешить или запретить доступ членов к объекту.

Итак, я думаю, что разница в том, что анонимные типы - это истинные POCOs, которые может видеть компилятор, но вы можете использовать их, а динамические типы - это связанные с поздними динамическими объектами.

Ответ 2

Кажется, вы смешиваете три совершенно разные ортогональные вещи:

  • статическая и динамическая типизация
  • манифест против неявной типизации
  • с именем против анонимных типов

Эти три аспекта полностью независимы, им нечего делать друг с другом.

Статическая или динамическая типизация относится к тому, когда происходит проверка типа: динамическая типизация выполняется во время выполнения, статическая типизация выполняется до выполнения.

Манифест против неявной типизации относится к тому, являются ли типы явными в исходном коде или нет: манифестное типирование означает, что программист должен записывать типы в исходный код, неявное типирование означает, что система типов вычисляет их на своем самостоятельно.

Именованные или анонимные типы ссылаются на то, имеют ли типы имена или нет.

Ключевое слово dynamic в С# 4.0 означает, что эта переменная, параметр, метод, поле, свойство... независимо от того, что динамически типизировано, т.е. что его тип будет проверяться во время выполнения. Все, что не типизировано как динамическое, статически типизировано. Является ли тип статическим или динамическим, не только определяет, когда происходит проверка типа, но и в С# 4.0, он также определяет, когда происходит отправка метода. В С# отправка метода выполняется во время выполнения на основе статического типа (за исключением полиморфизма подтипов времени выполнения), тогда как на динамически типизированных объектах в С# 4.0 отправка метода выполняется во время выполнения на основе типа среды выполнения.

Ключевое слово var в С# 3.0 означает, что эта локальная переменная будет неявно введена, т.е. что вместо программиста, записывающего тип явно, система типов сама по себе решит. Это не имеет ничего общего с динамической типизацией, по крайней мере, в С# 3.0. Переменная будет сильно статически введена так же, как если бы вы сами записали тип. Это просто удобство: например, зачем вам записывать все имена типов дважды в HashMap<int, string> foo = new HashMap<int, string>();, когда система типов может четко определить, что foo является HashMap<int, string>, поэтому вместо этого вы пишете var foo = new HashMap<int, string();, Обратите внимание, что в этом нет ничего динамичного или анонимного. Тип является статическим и имеет имя: HashMap<int, string>. Конечно, в С# 4.0, если система типов определяет, что правая часть назначения динамическая, тип переменной в левой части будет динамическим.

Анонимный тип в С# 3.0 означает, что этот тип не имеет имени. Ну, на самом деле, реальные анонимные типы потребовали бы обратно-несовместимого изменения в Common Type System, так что на самом деле происходит за занавеской, так это то, что компилятор будет генерировать очень длинное, очень случайное, уникальное и незаконное имя для типа и put это имя, где появляется анонимный тип. Но с точки зрения программиста тип не имеет имени. Почему это полезно? Ну, иногда у вас есть промежуточные результаты, которые вам нужны только вкратце, а затем снова выбрасывать. Предоставление таких переходных типов само по себе могло бы повысить их до уровня важности, которого они просто не заслуживают. Но опять же, в этом нет ничего динамичного.

Итак, если тип не имеет имени, как программист может обратиться к нему? Ну, она не может! По крайней мере, не напрямую. Что программист может сделать, описывается тип: он имеет два свойства, одно из которых называется "имя" типа string, другое - "id" типа int. Это тип, который я хочу, но мне все равно, что он назвал.

Здесь куски начинают собираться вместе. В С# вы должны объявлять типы локальных переменных, явно записывая имена типов. Но как вы можете записать имя типа, у которого нет имени? Здесь встречается var: поскольку с С# 3.0 это на самом деле больше не верно: вам больше не нужно записывать имена, вы также можете сказать компилятору, чтобы понять это. Итак, хотя то, что я написал в первом абзаце выше, верно, что неявные типизации и анонимные типы не имеют ничего общего с другими, также верно, что анонимные типы были бы бесполезны без неявной типизации.

Обратите внимание, однако, что противоположное неверно: неявное типирование совершенно полезно без анонимных типов. var foo = HashMap<int, string> имеет смысл и нет анонимного типа в поле зрения.

Ответ 3

Тип dynamic по существу object, но будет разрешать все вызовы метода/свойства/оператора и т.д. во время выполнения через DLR или другой провайдер (например, отражение).

Это делает его очень похожим на VB с Option Strict Off и делает его очень универсальным для вызова в COM или в типы DLR.

Нет проверки типа во время компиляции с динамическим; conovedely, анонимные типы являются правильными статическими типизированными, проверенными по типу животными (вы можете видеть их в отражателе, хотя они не очень хороши).

Кроме того, анонимные типы могут обрабатываться исключительно компилятором; dynamic требует обширной поддержки во время выполнения, поэтому анонимные типы - это функция С#, но dynamic будет в значительной степени реализована .NET 4.0 (с некоторой поддержкой С# 4.0).

Ответ 5

Там три раза, с тремя актерами - по одному за раз.

  • Время разработки - программист
  • Компилятор compile-time - С#
  • Время выполнения -.net runtime

Анонимные типы объявляются именоваются компилятором. Это выражение основано на спецификации программиста (как он использовал тип). Поскольку эти типы называются после того, как программист покинул процесс, они, как представляется, являются безымянными для программиста, следовательно, являются "анонимными".

  • Программист говорит: у какого-то типа есть имя и адрес
  • Компилятор говорит: существует тип с именем xyz с именами и адресами Name и Address, обе строки.
  • runtime говорит: я не могу сказать никакой разницы между xyz и любым типом, который сделал программист.

динамическая вставка в С# позволяет вам вызывать методы, которые могут или не могут существовать во время компиляции. Это полезно для вызова в python или javascript, которые не скомпилированы.

  • Программист говорит: рассматривайте этот экземпляр автомобиля как динамический. Теперь, шарлатан.
  • Компилятор говорит: динамическая типизация eh? должно быть хорошо. Я не буду жаловаться, потому что я не могу это проверить.
  • Среда выполнения пытается создать экземпляр автомобиля, quack.

Ответ 6

Ничего похожего на маленький код, чтобы прояснить ситуацию:

// anonymous types
var anonType = new {Id = "123123123", Name = "Goku", Age = 30, DateAdded = new DateTime()};
// notice we have a strongly typed anonymous class we can access the properties with
Console.WriteLine($"Anonymous Type: {anonType.Id} {anonType.Name} {anonType.Age} {anonType.DateAdded}");
// compile time error
//anonType = 100;

// dynamic types
dynamic dynType = 100.01m;
Console.WriteLine($"Dynamic type: {dynType}");
// it ok to change the type however you want
dynType = new List<DateTime>();
Console.WriteLine($"Dynamic type: {dynType}");

// mix dynamic and anonymous
dynamic dynamicAnonymousType = new {Id = 8000, FirstName = "Goku", Gender = "male", IsSuperSaiyan = true};
// Wasn't sure this would work but it does! However, you lose intellisense on the FirstName so you have to type it manually.
Console.WriteLine($"FirstName: {dynamicAnonymousType.FirstName}");
dynamicAnonymousType = 100;
Console.WriteLine(dynamicAnonymousType);
// runtime error
Console.WriteLine($"Id: {dynamicAnonymousType.FirstName}");