Вы, кажется, смешиваете три совершенно разные, ортогональные вещи:
- статический или динамический ввод
- манифест против неявного ввод
- именованные и анонимные типы
Эти три аспекта полностью независимы, они не имеют ничего общего друг с другом.
Статическая или динамическая типизация относится к , когда происходит проверка типа: динамическая типизация происходит в время выполнения , статическая типизация происходит до выполнения .
Манифест против неявной типизация указывает, являются ли типы манифестами в исходном коде или нет: манифест тип означает, что программист должен написать вводит в исходный код, неявная типизация означает, что система типов вычисляет их самостоятельно.
Именованные и анонимные типы относится к тому, есть ли у типов имена или нет.
Ключевое слово dynamic
в C # 4.0 означает, что эта переменная, параметр, метод, поле, свойство ... независимо от того, динамически типизирован , то есть его тип будет проверяться во время выполнения. Все, что не типизировано как динамическое, статически типизировано. Является ли тип статическим или динамическим, не только определяет, когда происходит проверка типа, но и в C # 4.0 он также определяет, когда происходит отправка метода . В C # диспетчеризация метода выполняется перед выполнением на основе статического типа (за исключением, конечно, полиморфизма подтипа во время выполнения), тогда как для динамически типизированных объектов в C # 4.0 диспетчеризация метода выполняется во время выполнения на основе типа среды исполнения.
Ключевое слово var
в C # 3.0 означает, что эта локальная переменная будет неявно типизирована , т. Е. Вместо того, чтобы программист явно записывал тип, система типов сама определит его. Это не имеет ничего общего с динамической типизацией, по крайней мере, в C # 3.0. Переменная будет строго типизирована так же, как если бы вы сами записали тип. Это просто удобство: например, зачем вам записывать все имена типов дважды в HashMap<int, string> foo = new HashMap<int, string>();
, когда система типов может ясно выяснить, что foo
HashMap<int, string>
, поэтому вместо этого вы пишете var foo = new HashMap<int, string();
. Обратите внимание, что в этом нет ничего динамичного или анонимного. Тип является статическим и имеет имя: HashMap<int, string>
. Конечно, в C # 4.0, если система типов обнаруживает, что правая часть присваивания является динамической, то тип переменной в левой части будет динамическим.
анонимный тип в C # 3.0 означает, что этот тип не имеет имени. Ну, на самом деле, real анонимным типам потребовалось бы изменение, несовместимое с предыдущими версиями, в Common Type System, так что на самом деле происходит за кулисами, это то, что компилятор будет генерировать очень долго, очень случайное, уникальное и недопустимое имя для типа и поместите это имя везде, где появляется анонимный тип. Но с точки зрения программиста тип не имеет имени. Почему это полезно? Ну, иногда у вас есть промежуточные результаты, которые вам нужны только на короткое время, а затем выбрасывайте снова. Предоставление таким временным типам собственных имен повысит их до уровня важности, которого они просто не заслуживают. Но опять же, в этом нет ничего динамичного.
Итак, если тип не имеет имени, как программист может ссылаться на него? Ну, она не может! По крайней мере, не напрямую. Программист может сделать, описать тип: он имеет два свойства, одно из которых называется «имя» типа string
, другое - «id» типа int
. Это тот тип, который я хочу, но мне все равно, как он называется.
Вот где кусочки начинают собираться вместе. В C # вы должны объявлять типы локальных переменных, явно записывая имена типов. Но как вы можете записать имя типа, у которого нет имени? Вот тут и приходит var
: поскольку начиная с C # 3.0, это на самом деле уже не так: вам больше не нужно записывать имена, вы также можете сказать компилятору выяснить это. Итак, хотя то, что я написал в первом абзаце выше, верно, что неявная типизация и анонимные типы не имеют ничего общего с другими, также верно, что анонимные типы были бы довольно бесполезны без неявной типизации.
Обратите внимание, однако, что обратное неверно: неявная типизация очень полезна без анонимных типов. var foo = HashMap<int, string>
имеет смысл, и в поле зрения нет анонимного типа.