Итак, мы пишем:
Customer c = new Customer();
Почему дизайн не такой, что мы пишем:
c = new Customer();
c.CreditLimit = 1000;
Компилятор может определить c пунктов для Клиента и позволить членам Клиента вызываться на c?
Я знаю, что мы можем написать:
IPerson c = new Customer();
IPerson e = new Employee();
чтобы можно было написать:
public string GetName(IPerson object)
{
return object.Name
}
string name = GetName(c); // or GetName(e);
Но если бы мы написали:
c = new Customer();
e = new Employee();
мы могли бы еще написать:
public string GetName(object)
{
return object.Name
}
string name = GetName(c); // or GetName(e);
Компилятор может жаловаться на приведенный выше код, если тип ссылки на объект c не поддерживает свойство Name (так как он может проверять, какие члены используются в аргументе / параметре в методе), или среда выполнения может жаловаться.
Даже с динамическим ключевым словом C # мы все еще используем переменную type (определяется во время выполнения). Но зачем переменной вообще нужен тип? Я уверен, что должна быть веская причина, но я не могу думать об этом!
var
в C #, и всегда хорошо знать, где вы хотите объявить переменную.Ответы:
источник
a = new Bar()
а затем вызываете метод из классаBaz
), компилятор вызывает ошибку. Такие языки, как Haskell и OCaml, впервые применили вывод типов, но он присутствует в C # сvar
ключевым словом.У вас есть абсолютно правильная точка зрения, языки, которые не отслеживают тип переменной, существуют и называются «динамически типизированными». В эту категорию входят такие языки, как JavaScript, Perl, Lisp и Python.
Преимущество, которое мы получаем от статически типизированного языка, заключается в дополнительной проверке ошибок во время компиляции.
Предположим, например, что у вас есть следующий метод:
Было бы возможно, если у вас есть клиент
bob
и сотрудникjames
в вашем коде, чтобы по ошибке позвонитьaddCustomerContact(james, bob)
, что является недействительным. Но если компилятор не знает типы переменных, он не может предупредить вас о том, что вы сделали неверный вызов, вместо этого возникает ошибка во время выполнения ... и поскольку языки с динамической типизацией не проверяют Тип параметров, передаваемых в методы, эта проблема возникает всякий раз, когда ваш код пытается использовать свойстваjames
объекта только для клиента или свойства объекта только для сотрудникаbob
. Это может занять много времени после того, как пара (james, bob) была добавлена в список контактов с клиентами.Теперь вы можете задаться вопросом, почему компилятор не может определить тип
james
иbob
, и при этом предупредить нас? Иногда это возможно, но если переменные действительно не имеют типа, то мы можем сделать следующее:Вполне допустимо присваивать любое значение любой переменной, поскольку мы сказали, что переменные не имеют типа. Это также означает, что мы не всегда можем знать тип переменной, потому что это могут быть разные типы, основанные на разных путях выполнения.
В целом, языки с динамической типизацией используются для языков сценариев, где нет этапа компиляции, и поэтому ошибок компиляции не существует, а это означает, что дополнительные нажатия клавиш, необходимые для задания типа переменных, не будут очень полезными.
У динамически типизированных языков также есть некоторые явные преимущества, в основном с точки зрения меньшего количества кода, необходимого для реализации одного и того же проекта: интерфейсы не должны быть написаны, потому что все «типизировано по типу утки» (нас интересует только то, какие методы / свойства у объекта есть). , а не к какому классу принадлежит объект), переменным не нужно задавать явный тип ... с компромиссом, который мы узнаем о несколько меньшем количестве ошибок, прежде чем мы начнем запускать наш код.
источник
Таким образом, профессиональные программисты не должны выяснять,
Что это за ошибка, во время компиляции со статически типизированным языком или во время выполнения с динамически типизированным. Ну, в любом случае, вменяемые.
источник
Предполагая, что у вас есть переменная
one
(установлена в 1) и вы пытаетесь оценитьone + one
. Если вы не имели представления о типе, то 1 + 1 будет неоднозначным. Вы можете утверждать, что 2 или 11 могут быть правильными ответами. Это становится неоднозначным, если контекст не задан.Я видел это происходит в SQLite , где типы баз данных неумышленно установлены в
VARCHAR
вместоINT
и когда были сделаны операции люди получали неожиданные результаты.В c #, если контекст выводит тип, вы можете использовать
var
ключевое слово.Скомпилирует c и e с предполагаемыми типами во время компиляции.
источник
1 + 1
всегда есть типint
, но нет необходимости объявлять это. Вопрос в том, почему переменные имеют тип, а не значения .variables
неvalues
когда я1 + 1
в моем примере. Я думаю, это не было ясно.one=1; print(one+one)
печатает2
.one="1"; print(one+one)
отпечатки11
. Пример SQLite более убедителен, но проблема заключается в слабой типизации, поэтому он не очень актуален для C #.ORDER BY
неосторожности наVARCHAR
поле. См. Stackoverflow.com/questions/9103313/… .Переменная не должна иметь связанный тип. К таким языкам относятся Лисп, Схема, Эрланг, Пролог, Smalltalk, Perl, Python, Ruby и другие.
Переменная также может иметь тип, но вам может не потребоваться записать тип в программе. Это обычно называется выводом типа. ML, Haskell и их потомки имеют мощный вывод типа; некоторые другие языки имеют его в меньших формах, таких как объявления C ++
auto
.Основным аргументом против вывода типа является то, что он ухудшает читабельность. Обычно код легче понять, когда типы записаны.
источник
Когда вы определяете тип, который представляет ваша переменная, вы делаете заявление о нескольких вещах. Вы определяете требования к выделению памяти для своей переменной и определяете правила совместимости и диапазона для своей переменной. Он позволяет избежать путаницы в отношении ваших намерений в отношении данных, которые вы храните, и предоставляет вам относительно дешевые средства для выявления потенциальных проблем в вашем коде во время компиляции.
Если вы объявите следующие переменные:
Что вы можете сделать из этих переменных? Является
myVar
знаком или без знака? Это 8-битный, 64-битный или что-то среднее? ЯвляетсяmyOtherVar
ли String (фактически массив) или Char? Это ANSI или Unicode?Предоставляя конкретные типы данных, вы предоставляете компилятору подсказки о том, как он может оптимизировать требования к памяти для вашего приложения. Некоторые языки не сильно беспокоятся об этом, позволяя решать эти вопросы во время выполнения, тогда как другие языки допускают определенное количество динамической типизации, потому что, анализируя код, можно определить типы данных.
Еще один момент, связанный со строго типизированными языками, заключается в том, что он избавляет вас от необходимости давать инструкции компилятору каждый раз, когда вы используете переменную. Можете ли вы представить, насколько ужасным и нечитабельным стал бы ваш код, если бы каждый раз, когда вы обращались к переменной, вы были вынуждены эффективно приводить ее, чтобы сообщить компилятору, какой это тип значения? !!
источник
Компьютерная программа - это граф узлов процесса, описывающий, что должна делать «машина», представленная языковой средой исполнения (в большинстве случаев расширенной с помощью наборов инструментов), в каком порядке или при каких условиях. Этот график представлен текстовым файлом (или набором текстовых файлов), написанным на определенном языке и (частично или полностью) созданным, когда компилятор / интерпретатор читает (десериализует) этот файл. Кроме того, есть некоторые среды (UML или инструменты для создания графических программ), где вы можете построить этот график и сгенерировать исходный код на целевом языке.
Почему я это говорю? Потому что это приводит к ответу на ваш вопрос.
Текст вашей программы - это ваши указания о том, как компьютер должен решать реальную задачу, содержащий как этапы процесса (условия, действия), так и структуру (какие компоненты вы используете в решении). Последнее означает, что вы получаете или создаете некоторые экземпляры других компонентов, помещаете их в именованные блоки (переменные) и используете их: обращаетесь к их данным и услугам.
В некоторых языках есть единообразные блоки, в которых важна только метка, но вы можете поместить в них что угодно, вы даже можете использовать переменную с именем «target» для хранения «Person» в начале и «Car» в конце тот же алгоритм. Другие требуют, чтобы вы создали «фасонные» боксы, поэтому разные для человека или автомобиля - хотя они по-прежнему позволяют создавать «универсальный бокс» (Java Object, C / C ++ void *, Objective C «id» ...) и брось как хочешь. Типизированные языки позволяют вам выразить свою структуру в мельчайших деталях, создавая «контракты типов» для ваших переменных (хотя вы можете обойти это ограничение), в то время как нетипизированные языки поддерживают этот подход «я наверняка буду знать, что я поместил в этот блок в этот раз» по умолчанию и единственное поведение.
Оба подхода жизнеспособны, имеют свой интеллект компилятора, много книг по программированию, практики и фреймворки, написанные с их использованием (и другие тонны книг об этих фреймворках) на разных уровнях. Таким образом, сегодня ответ кажется скорее вопросом вкуса и знаний действительной команды программистов, чем правильно обоснованным, взвешенным и проверенным утверждением о том, использовать или не использовать типы.
Я думаю, что нет необходимости говорить, что я предпочитаю правила трюкам, особенно для долгосрочных, больших командных проектов (иначе говоря, «серьезных»). Причина: насколько я знаю, наиболее вероятные причины неудачи / проскальзывания проекта ПО: неясные требования и плохой дизайн (80%! По моим исследованиям), и только несколько процентов остается для фактического кодирования. Все правила и контракты обеспечивают более четкое проектирование, продуманность и требуют решений, которые должны быть приняты ранее и соответствующими людьми. Типы означают правила: меньше «свободы» и «крутости» - больше подготовки, мышления, стандартов кодирования, контролируемой командной работы. Для меня это звучит как необходимый фактор успеха, а также «дом, милый дом».
Мои 2 цента.
источник
AFIAK все языки с динамической типизацией являются интерпретируемыми языками. Это уже очень неэффективно, добавление неэффективности динамической типизации не будет большой потерей времени. Однако скомпилированный язык не будет ссылаться на вещи по имени, когда он работает. (Исключая случайное использование отражения .net и т. П. - функций, которые очень медленны по сравнению с базовым языком.) Поиск всех этих имен будет медленным, медленным, медленным.
источник
Динамически типизированные языки часто рекламируются как «объектно-ориентированные». Они не. Они могут быть ориентированы на инкапсуляцию, но никогда не объектно-ориентированы. Ориентация на объект - это все о типах.
«Мальчик едет на велосипеде своего брата в продуктовый магазин и покупает булку хлеба у бакалейщика». Используя объектную ориентацию, можно сразу написать набор классов (типов) для описания этого реального сценария.
В динамически типизированном языке сценарий может быть представлен только так:
«Объект ездит на объекте своего объекта к объекту и покупает объект у объекта».
Сила объектной ориентации заключается в ее способности моделировать мир в естественных терминах, так что разработчик программного обеспечения может использовать обе стороны мозга для написания программного обеспечения и решать проблемы больше как человек, а не как программист. Эта сила отсутствует в динамически типизированных языках.
Статическая типизация обеспечивает лучшую эффективность кодирования, возможность повторного использования и удобство обслуживания, потому что интегрированные среды разработки знают типы переменных. Зная типы переменных, IDE может обеспечить автоматическое завершение, так что программисту не нужно возвращаться к определению класса, чтобы запомнить, было ли свойство члена записано как «backlightControl» или «backLightControl» или «bkLightCtrl».
Статическая типизация допускает автоматический рефакторинг, поскольку среда IDE знает все места, где переменная содержит экземпляр рефакторинга объекта.
Статическая типизация допускает повторное использование и ремонтопригодность. Динамическая печать лучше подходит для одноразового кода. Предположим, новый разработчик приходит с улицы и смотрит на существующий фрагмент кода. Если код статически типизирован, разработчик может в два клика мыши проверить определение класса каждой из задействованных переменных, знает, для чего предназначен класс, знает, какие другие методы и свойства доступны. Если код динамически типизирован, разработчик должен использовать глобальный поиск, чтобы выяснить, что происходит.
источник
Boy
класс, но я сомневаюсь, что он может делать все, что в реальном мире делает "мальчик". Однако в вашем динамическом примере (объект едет ...) мы знаем единственную важную вещь об этом "мальчишеском" объекте - он может ездить . Это основная философия языков динамического типа. У него есть + ve s и -ve s. Какой вам нравится, ваше мнение.