Мне кажется странным, что только программисты на C # и Java, похоже, страдают от недуга, который не позволяет им извлекать информацию из контекста кода, в то время как разработчики Python, JavaScript, Ruby, F #, Haskell и других, похоже, неуязвимы для этот. Почему у них, кажется, все в порядке, но нам, программистам на C #, нужно это обсудить?
Если вышеприведенные явные объявления типов неряшливы или ленивы, значит ли это, что нет качественного читаемого кода Python? На самом деле, не многие ли хвалят Python за читабельность? И есть много вещей, которые меня раздражают в динамической типизации в JavaScript, но отсутствие явных объявлений типов не является одним из них.
Вывод типа в статически типизированных языках должен быть нормой, а не исключением; это уменьшает визуальный беспорядок и избыточность, в то же время делая ваше намерение более ясным, когда вы делаете явно указываете тип, потому что вы хотите менее производный тип (IList<int> list = new List<int>();
).
Некоторые могут возразить против var
, как это:
var c = SomeMethod();
Что ж, я бы сказал, что вы должны дать своим переменным более разумные имена.
Улучшено:
var customer = SomeMethod();
Лучше:
var customer = GetCustomer();
Попробуем явный ввод:
Customer customer = GetCustomer();
Какая информация у вас сейчас есть, которой у вас не было раньше? Теперь вы наверняка знаете, что это тип Customer
, но вы уже знали это, верно? Если вы уже знакомы с кодом, вы знаете, какие методы и свойства вы можете ожидать в customer
, просто по имени переменной. Если вы еще не знакомы с кодом, вы не знаете, какие методы у Customer
есть. Явный тип здесь ничего не добавляет.
Возможно, некоторые противники var
могут признать, что в приведенном выше примере var
не причиняет вреда. Но что, если метод не возвращает простой и хорошо известный тип, такой как Customer
или Order
, но какое-то обработанное значение, такое как словарь? Что-то вроде:
var ordersPerCustomer = GetOrdersPerCustomer();
Я не знаю, что это возвращает, может быть словарь, список, массив, что угодно. Но имеет ли это значение? Из кода я могу сделать вывод, что у меня будет итеративная коллекция клиентов, где каждый Customer
в свою очередь содержит итеративную коллекцию Order
. Мне действительно наплевать на тип здесь. Я знаю, что мне нужно знать, если выясняется, что я не прав, виноват метод, который вводит меня в заблуждение своим именем, что-то, что не быть исправлено явным объявлением типа.
Давайте посмотрим на явную версию:
IEnumerable<IGrouping<Customer,Order>> ordersPerCustomer = GetOrdersPerCustomer();
Я не знаю о вас, но мне намного сложнее извлечь из этого нужную мне информацию. Не в последнюю очередь потому, что бит, который содержит фактическую информацию (имя переменной), находится дальше вправо, где мне потребуется больше времени, чтобы найти ее, визуально скрытую всеми этими сумасшедшими <
и >
. Фактический тип бесполезен, это бред, особенно потому, что для понимания этого вам нужно знать, что делают эти универсальные типы.
Если в какой-то момент вы не уверены, что метод или какая переменная содержит, просто по имени, вам следует дать ему лучшее имя. Это гораздо ценнее, чем видеть, какой это тип.
Явная типизация не должна быть необходимой , если это так, то с вашим кодом что-то не так, а не с выводом типа. Это не может быть необходимым, так как другие языки, очевидно, тоже не нуждаются.
Тем не менее, я склонен использовать явную типизацию для «примитивов», таких как int
и string
. Но, честно говоря, это скорее привычка, а не сознательное решение. Что касается чисел, то вывод типа может привести вас в замешательство, если вы забудете добавить m
к буквальному номеру, который вы хотите ввести как decimal
, что достаточно легко сделать, но компилятор не позволит вам случайно потерять точность, так что это не актуальная проблема. На самом деле, если бы я использовал var
везде, в большом приложении, над которым я работаю, менялось бы гораздо большее изменение величин с целых чисел на десятичные.
Что является еще одним преимуществом var
: он позволяет быстро экспериментировать, не заставляя вас обновлять типы везде, чтобы отразить ваши изменения.Если я хочу изменить приведенный выше пример на Dictionary<Customer,Order>[]
, я могу просто изменить свою реализацию, и весь код, который вызвал ее с var
, продолжит работать (ну, по крайней мере, объявления переменных).