После обсуждения с коллегами относительно использования ключевого слова 'var' в C # 3 мне стало интересно, что люди думают о правильном использовании вывода типа через var?
Например, я довольно лениво использовал var в сомнительных обстоятельствах, например:
foreach(var item in someList) { // ... } // Type of 'item' not clear.
var something = someObject.SomeProperty; // Type of 'something' not clear.
var something = someMethod(); // Type of 'something' not clear.
Более законные варианты использования var:
var l = new List<string>(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.
Интересно, что LINQ выглядит немного серым, например:
var results = from r in dataContext.SomeTable
select r; // Not *entirely clear* what results will be here.
Ясно, какие результаты будут в том, что это будет тип, который реализует IEnumerable, однако это не совсем очевидно в том же смысле, что и var, объявляющий новый объект.
Еще хуже, когда речь идет о LINQ для объектов, например:
var results = from item in someList
where item != 3
select item;
Это не лучше, чем эквивалентный foreach (var item в someList) {// ...} эквивалентный.
Здесь существует реальная проблема безопасности типов - например, если бы мы поместили результаты этого запроса в перегруженный метод, который принимал IEnumerable <int> и IEnumerable <double>, вызывающая сторона могла бы непреднамеренно передать неправильный тип.
var
действительно поддерживает строгую типизацию, но вопрос в том, действительно ли опасно, чтобы тип не был сразу очевиден при определении, что усиливается, когда перегрузки означают, что ошибки компилятора могут не возникать, когда вы непреднамеренно передаете неправильный тип методу.
источник
var i = 0;
== провал!var c = new CrazyFrigginLongClassName();
== победить!var readabilityBeDamned = true;
Ответы:
Я все еще думаю, что
var
может сделать код более читабельным в некоторых случаях. Если у меня есть класс Customer со свойством Orders, и я хочу присвоить его переменной, я просто сделаю это:Меня не волнует , если Customer.Orders есть
IEnumerable<Order>
,ObservableCollection<Order>
илиBindingList<Order>
- все , что я хочу, чтобы сохранить этот список в памяти для итерации по нему или получить его счет или что - то позже.Сравните приведенную выше декларацию с:
Для меня имя типа просто шум. И если я вернусь и решу изменить тип Customer.Orders вниз по дорожке (скажем, от
ObservableCollection<Order>
доIList<Order>
), то мне нужно тоже изменить это объявление - что-то, что мне не пришлось бы делать, если бы я использовал var в первом место.источник
Я пользуюсь
var
экстенсивно. Была критика, что это снижает читабельность кода, но нет аргументов в поддержку этого утверждения.Правда, это может означать, что не ясно, с каким типом мы имеем дело. И что? Это на самом деле точка развязанного дизайна. Имея дело с интерфейсами, вы решительно не интересуетесь типом переменной.
var
правда, это гораздо дальше, но я думаю, что аргумент остается неизменным с точки зрения читабельности: программист должен интересоваться не типом переменной, а тем, что делает переменная . Вот почему Microsoft также называет вывод типа «утка».Итак, что делает переменная, когда я объявляю ее используя
var
? Легко, он делает то, что мне говорит IntelliSense. Любые рассуждения о C #, которые игнорируют IDE, не соответствуют действительности. На практике каждый код C # программируется в среде IDE, которая поддерживает IntelliSense.Если я использую
var
объявленную переменную и запутываюсь, для чего эта переменная, в моем коде что-то принципиально не так.var
это не причина, это только делает симптомы видимыми. Не вините посланника.Теперь команда C # выпустила руководство по кодированию, в котором говорится, что его
var
следует использовать только для захвата результата оператора LINQ, который создает анонимный тип (потому что здесь у нас нет реальной альтернативыvar
). Ну, винт это. Пока команда C # не дает мне веских аргументов в пользу этого руководства, я буду игнорировать его, потому что, по моему профессиональному и личному мнению, это чистый вздор. (Извините, у меня нет ссылки на данный вопрос.)На самом деле, есть несколько (поверхностно) хороших объяснений того, почему вы не должны их использовать,
var
но я все еще считаю, что они в значительной степени ошибочны. Возьмите пример «searchabililty»: автор утверждает, чтоvar
затрудняет поиск мест, гдеMyType
он используется. Правильно. Так же и интерфейсы. На самом деле, почему я хотел бы знать, где используется класс? Возможно, меня больше интересует, где он создается, и он все равно будет доступен для поиска, потому что где-то должен вызываться его конструктор (даже если это делается косвенно, имя типа должно упоминаться где-то).источник
var
способствует путанице. Конечно, могут быть случаи, когда важно подчеркнуть тип / размер переменной (например, операции с битами низкого уровня). Это нормально: никто никогда не утверждал, чтоvar
должен использоваться исключительно. Правило простое: если оно действительно вызывает путаницу, не используйте его.Вар, на мой взгляд, в C # это хорошая вещь, тм . Любая переменная с таким типом все еще строго типизирована, но она получает свой тип из правой части присваивания, где она определена. Поскольку информация о типе доступна с правой стороны, в большинстве случаев нет необходимости и слишком многословно вводить ее также с левой стороны. Я думаю, что это значительно повышает читаемость без снижения безопасности типов.
С моей точки зрения, использование хороших соглашений об именах для переменных и методов более важно с точки зрения читабельности, чем явная информация о типах. Если мне нужна информация о типе, я всегда могу навести курсор на переменную (в VS) и получить ее. Как правило, однако, явная информация о типе не должна быть необходимой для читателя. Для разработчика в VS вы по-прежнему получаете Intellisense, независимо от того, как объявлена переменная. Сказав все это, все еще могут быть случаи, когда имеет смысл явно объявить тип - возможно, у вас есть метод, который возвращает a
List<T>
, но вы хотите рассматривать его какIEnumerable<T>
в вашем методе. Чтобы убедиться, что вы используете интерфейс, объявление переменной типа интерфейса может сделать это явным. Или, возможно, вы хотите объявить переменную без начального значения - потому что она сразу же получает значение на основе некоторого условия. В этом случае вам нужен тип. Если информация о типе полезна или необходима, используйте ее. Однако я чувствую, что, как правило, в этом нет необходимости, и в большинстве случаев код легче читать без него.источник
Ни один из них не является абсолютно верным;
var
может оказывать как положительное, так и отрицательное влияние на читабельность. На мой взгляд,var
следует использовать, когда выполняется одно из следующих условий:var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating()
)var
не влияет на производительность, так как это синтаксический сахар; компилятор выводит тип и определяет его, как только он скомпилирован в IL; нет ничего на самом деле динамического об этом.источник
typedef
когда это не так.var
когда тип очевиден? Возможно, но истинная выгода - это когда тип не имеет значения. Если вы делаете подобные вещи,var customers = whatever; var query = from c in customers select stuff
не имеет значения, какой именно тип «клиентов». Понятно, как это можно использовать, и этого достаточно. И если фактический тип громоздок, стоит его подавить.using ShortType = LongGenericType<A,B,C>
директиву в верхней части файла, поскольку она обеспечивает одинаковую читаемость, не требует повторного создания конструкторов и не исключает дочерние классы из числа кандидатов.От Эрика Липперта, старшего инженера-разработчика программного обеспечения в команде C #:
Почему было
var
введено ключевое слово?Акцент мой. Целая статья, C # 3.0 все еще статически напечатана, честно! и последующие серии довольно хороши.
Это для чего
var
. Другое использование, вероятно, не будет работать так хорошо. Любое сравнение с JScript, VBScript или динамической типизацией является полной накладкой. Примечание снова,var
это требуется для того , чтобы иметь некоторые другие особенности работы в .NET.источник
Я думаю, что использование var должно сочетаться с мудро выбранными именами переменных.
У меня нет проблем с использованием var в выражении foreach при условии, что это не так:
Если бы это было больше так:
... тогда кто-то, читающий код, с большей вероятностью поймет, что такое «список». Если у вас есть контроль над именем самой переменной списка, это даже лучше.
То же относится и к другим ситуациям. Это довольно бесполезно:
... но это имеет смысл:
Кажется, каждому свое. Я обнаружил, что делаю это, что просто безумие:
Мне нужна какая-то 12-шаговая вар-программа. Меня зовут Мэтт, и я (ab) использую вар.
источник
Мы приняли принцип «Код для людей, а не для машин», исходя из того, что в режиме обслуживания вы тратите в несколько раз больше времени, чем на новые разработки.
Для меня это исключает аргумент, что компилятор «знает», какой тип переменной - конечно, вы не можете написать неверный код в первый раз, потому что компилятор останавливает компиляцию вашего кода, но когда следующий разработчик читает код через 6 месяцев они должны быть в состоянии определить, что переменная делает правильно или неправильно, и быстро определить причину проблем.
Таким образом,
запрещено нашими стандартами кодирования, но в нашей команде рекомендуется следующее, поскольку это повышает удобочитаемость:
источник
Это не плохо, это скорее стилистическая вещь, которая имеет тенденцию быть субъективной. Это может добавить несоответствия, когда вы используете var, а когда нет.
Другой случай, вызывающий беспокойство, в следующем вызове вы не можете определить, просто посмотрев код, возвращаемый типом
CallMe
:Это моя главная жалоба на вар.
Я использую var, когда объявляю анонимные делегаты в методах, так или иначе, var выглядит чище, чем если бы я использовал
Func
. Рассмотрим этот код:РЕДАКТИРОВАТЬ : Обновлен последний пример кода на основе ввода Джулиана
источник
variable
? Если вы не расширите свой пример, это не очень серьезная жалоба, ИМО.variable
,CallMe
) являются плохими примерами. Однако, если бы этоCallMe()
была функция в каком-то «телефонном приложении»,var call = CallMe(); .... call.HangUp();
это имело бы гораздо больший смысл.Var совсем не похож на вариант. Переменная все еще строго типизирована, просто вы не нажимаете клавиши, чтобы получить ее таким образом. Вы можете навести на него курсор в Visual Studio, чтобы увидеть тип. Если вы читаете напечатанный код, возможно, вам придется немного подумать, чтобы понять, что это за тип. Но есть только одна строка, которая объявляет это, и много строк, которые его используют, так что присвоение приличных имен - все еще лучший способ облегчить выполнение вашего кода.
Использование Intellisense лениво? Он меньше печатает, чем целое имя. Или есть вещи, которые меньше работают, но не заслуживают критики? Я думаю, что есть, и Вар является одним из них.
источник
var
имеет ничего общего сVariant
.Скорее всего, вам понадобится это время для анонимных типов (где это требуется на 100%); но это также избегает повторения для тривиальных случаев, и IMO делает линию более четкой. Мне не нужно видеть тип дважды для простой инициализации.
Например:
(пожалуйста, не редактируйте hscroll выше - это как бы доказывает смысл !!!)
против:
Однако бывают случаи, когда это вводит в заблуждение и может привести к ошибкам. Будьте осторожны,
var
если исходная переменная и инициализированный тип не идентичны. Например:источник
Один конкретный случай, когда var сложен: проверка автономного кода, особенно те, которые сделаны на бумаге.
Вы не можете полагаться на наведение мыши для этого.
источник
Я не понимаю, в чем дело ..
У вас все еще есть полная интеллигентность по «чему-то», и для любого неоднозначного случая у вас есть свои юнит-тесты, верно? ( вы? )
Это не varchar, это не тусклый, и это, конечно, не динамическая или слабая типизация. Это останавливает maddnes как это:
и уменьшая эту общую суматоху до:
Хорошо, не так хорошо, как:
Но тогда для этого и нужен Бу .
источник
v = List<somethinglongtypename>();
даже лучше. Важно различать введение новой переменной и присвоение существующей переменной.Если кто-то использует
var
ключевое слово, потому что он не хочет «выяснить тип», это определенно неправильная причина.var
Ключевое слово не создает переменную с типом динамического, компилятор все равно должен знать тип. Поскольку переменная всегда имеет определенный тип, этот тип также должен быть очевиден в коде, если это возможно.Хорошие причины использовать
var
ключевое слово, например:Записывание типа данных часто облегчает выполнение кода. Он показывает, какие типы данных вы используете, так что вам не нужно выяснять тип данных, сначала выяснив, что делает код.
источник
Учитывая, насколько мощным теперь является Intellisense, я не уверен, что var сложнее для чтения, чем наличие переменных-членов в классе или локальных переменных в методе, которые определены вне видимой области экрана.
Если у вас есть строка кода, такая как
Гораздо проще или труднее читать, чем:
источник
Я думаю, что ключевым моментом в VAR является его использование только там, где это уместно, т. Е. При выполнении действий в Linq, которые это облегчает (и, вероятно, в других случаях).
Если у вас есть тип для чего-то, тогда вы должны его использовать - не делать это - просто лень (в отличие от творческой лени, которая обычно поощряется) - хорошие программисты часто работают очень усердно, чтобы быть ленивыми, и их можно считать источник вещи в первую очередь).
Общий запрет так же вреден, как и злоупотребление конструкцией, но должен быть разумный стандарт кодирования.
Другая вещь , чтобы помнить о том , что его не тип VB вар в том , что он не может изменить тип - это является строго типизированным переменным его только что тип выводятся (поэтому есть люди , которые будут утверждать , что его не неразумно используйте его, скажем, в foreach, но я не согласен по причинам как удобочитаемости, так и удобства обслуживания).
Я подозреваю, что этот собирается бежать и бежать (-:
Murph
источник
Конечно,
int
это легко, но когда тип переменнойIEnumerable<MyStupidLongNamedGenericClass<int, string>>
, var делает вещи намного проще.источник
int
Против этогоvar
есть что поспорить, но множественные вложенные универсальные типы делаютvar
находку. Именно здесь использование имени типа снова и снова нарушает читабельность кода.class IntStringEnumerator : IEnumerable<MyStupidLongNamedGenericClass<int, string>>
и затем используйте новое имя. Это очищает код и лучше описывает тип.IntStringEnumerator i = new IntStringEnumerator()
все еще слишком много печатать.Похищен из поста по этому вопросу на CodingHorror :
К сожалению, вы и все остальные в значительной степени ошиблись. Хотя я согласен с вами, что избыточность не очень хорошая вещь, лучшим способом решения этой проблемы было бы сделать что-то вроде следующего:
MyObject m = new ();
Или, если вы передаете параметры:
Person p = new ("FirstName", "LastName);
Где при создании нового объекта компилятор выводит тип с левой стороны, а не справа. Это имеет другие преимущества по сравнению с «var» в том смысле, что оно может быть использовано и в объявлениях полей (есть также некоторые другие области, которые могут быть полезны, но я не буду здесь вдаваться в подробности).
В конце концов, это просто не было предназначено для сокращения избыточности. Не поймите меня неправильно, «var» ОЧЕНЬ важен в C # для анонимных типов / проекций, но использование здесь просто ОТКЛЮЧЕНО (и я говорил это очень долго), когда вы запутываете тип, который используется. Потребность напечатать это дважды - слишком часто, но объявлять это нулем - слишком мало.
Николас Палдино .NET / C # MVP 20 июня 2008 г. 08:00
Я предполагаю, что если ваша главная задача - печатать меньше - тогда нет никаких аргументов, которые бы помешали вам его использовать.
Если вы когда-нибудь станете человеком, который смотрит на ваш код, то кого это волнует? В противном случае, в таком случае:
это хорошо, но в таком случае:
он замыкает любые непосредственные выводы типа, которые мой мозг может начать формировать из «английского» кода.
В противном случае, просто используйте свое суждение и программируйте «вежливость» по отношению к другим, кому, возможно, придется работать над вашим проектом.
источник
Использование
var
вместо явного типа значительно упрощает рефакторинг (поэтому я должен противоречить предыдущим постерам, которые имели в виду, что это не имеет значения, или это был просто «синтаксический сахар»).Вы можете изменить тип возврата ваших методов, не меняя каждый файл, где вызывается этот метод. Представить
который используется как
Если вы хотите выполнить рефакторинг
SomeMethod()
для возвратаIEnumerable<MySecondClass>
, вам придется изменять объявление переменной (также внутриforeach
) в каждом месте, где вы использовали метод.Если ты пишешь
вместо этого вам не нужно это менять.
источник
@aku: Одним из примеров являются обзоры кода. Другой пример - сценарии рефакторинга.
По сути, я не хочу охотиться за типами с помощью мыши. Это может быть недоступно.
источник
Это вопрос вкуса. Все эти разговоры о типе переменной исчезают, когда вы привыкаете к языкам с динамической типизацией. То есть, если они вам когда-нибудь начнут нравиться (я не уверен, что все могут, но мне это нравится).
C #
var
довольно круто в том смысле, что выглядит как динамическая типизация, но на самом деле это статическая типизация - компилятор обеспечивает правильное использование.Тип вашей переменной не так уж важен (об этом уже говорилось). Это должно быть относительно ясно из контекста (его взаимодействия с другими переменными и методами) и его имени - не ожидайте, что customerList будет содержать
int
...Я все еще жду, чтобы увидеть, что мой босс думает по этому поводу - я получил общее предложение «использовать» в 3.5 новые конструкции, но что мы будем делать с техническим обслуживанием?
источник
При сравнении между вами
IEnumerable<int>
иIEnumerable<double>
вам не нужно беспокоиться - если вы передадите неверный тип, ваш код все равно не скомпилируется.Там нет заботы о безопасности типов, так как не
var
является динамическим. Это просто магия компилятора, и любые небезопасные вызовы, которые вы делаете, будут пойманы.Var
абсолютно необходим для Linq:Теперь посмотрите на anonEnumeration в intellisense, и он будет выглядеть примерно так:
IEnumerable<'a>
Компилятор C # довольно умен - все типы, сгенерированные отдельно, будут иметь одинаковый сгенерированный тип, если их свойства совпадают.
Помимо этого, если у вас есть intellisense, имеет смысл использовать
var
везде, где ясен контекст.источник
IQueriable<T>
удалите, прежде чем повторять:anonEnumeration.ToList();
IQueryable
или.ToList()
var anonEnumeration = from post in AllPosts() where post.Date > oldDate let author = GetAuthor( post.AuthorId ) select new { PostName = post.Name, post.Date, AuthorName = author.Name };
не возвращаетIQueriable<T>
?AllPosts()
возвращает - спрашивает спрашивающий,List<T>
поэтому я предположил, что. В этом случае результатомanonEnumeration
будет типIEnumerable<'a>
. Теперь, если вместо этогоAllPosts()
возвращается,IQueryable<T>
тоanonEnumeration
станетIQueryable<'a>
(обратите внимание, нетi
в Queryable) - однако в этом случае мой код все еще работает, потому чтоIQueryable<T>
реализуетIEnumerable<T>
. Здесь есть множество лучших вопросов и ответов о различиях между ними - здесь мой случай - это'a
анонимность иvar
позволяет вам присвоить его статически типизированной переменной.IQueryable<T>
не является хорошей практикой, потому что на каждой итерации вы делаете оператор чтения в БД. Обязательно перед*.ToList()
IQueryable<T>
тем, как их повторитьЯ думаю, это зависит от вашей точки зрения. Лично у меня никогда не было трудностей с пониманием фрагмента кода из-за
var
«неправильного использования», и я и мои коллеги используем его довольно часто. (Я согласен, что Intellisense является огромной помощью в этом отношении.) Я приветствую это как способ устранения повторяющихся ошибок.В конце концов, если заявления как
было бы на самом деле невозможно иметь дело, никто не использовал бы динамически типизированные языки.
источник
Я использую var только тогда, когда ясно, какой тип используется.
Например, я бы использовал var в этом случае, потому что вы сразу видите, что x будет иметь тип «MyClass»:
Я бы НЕ использовал var в таких случаях, потому что вам нужно навести курсор мыши на код и посмотреть на всплывающую подсказку, чтобы увидеть, какой тип возвращает MyFunction:
Особенно я никогда не использую var в тех случаях, когда правая сторона - это даже не метод, а только значение:
(потому что компилятор не может знать, хочу ли я байта, short, int или что-то еще)
источник
var
, тоvar
проблема не в этом: проблема в правой стороне. Это не достаточно описательно .Customer c = GetContext()
до сих пор неясно и не лучше, чем использоватьvar
.Для меня антипатия к
var
иллюстрации иллюстрирует важность двуязычия в .NET. Для тех программистов на C #, которые также работали с VB .NET, преимуществаvar
очевидны. Стандартное объявление C #:это эквивалентно, в VB .NET, набирать это:
Никто не делает это в VB .NET, хотя. Было бы глупо, потому что начиная с первой версии .NET вы смогли сделать это ...
... который создает переменную и инициализирует ее в одну достаточно компактную строку. Ах, но что, если вы хотите
IList<string>
, а неList<string>
? Ну, в VB .NET это означает, что вы должны сделать это:Точно так же, как вы должны делать в C #, и, очевидно, не можете использовать
var
для:Если вам нужно, чтобы тип был чем-то другим, это может быть. Но один из основных принципов хорошего программирования - сокращение избыточности, и это именно то, что делает var.
источник
var
в C # не имеет никакого отношенияvar
к JavaScript.var
-Declared переменной в C # сильно типизированных.Используйте его для анонимных типов - вот для чего он нужен. Все остальное слишком далеко. Как и многие люди, выросшие на C, я привык смотреть на тип объявления слева от объявления. Я не смотрю на правую сторону, если мне не нужно. Использование
var
для любого старого объявления заставляет меня делать это все время, что лично мне неудобно.Те, кто говорит: «Неважно, используйте то, что вам нравится», не видят всей картины. Каждый в тот или иной момент подберет чужой код, и ему придется иметь дело с любыми решениями, которые они приняли во время написания. Достаточно плохо иметь дело с радикально различными соглашениями об именах или - с классическими стилями захвата, без добавления всего «
var
или нет» в микс. В худшем случае один программист не использовал его,var
а затем приходит сопровождающий, который любит его и расширяет код, используя его. Так что теперь у вас нечестивый беспорядок.Стандарты - это хорошая вещь именно потому, что они означают, что у вас гораздо больше шансов получить случайный код и быстро его получить. Чем больше вещей отличаются, тем сложнее становится. И переход к стилю «везде» имеет большое значение.
Я не против динамической типизации, и я не против имплицитной типизации - в языках, которые предназначены для них. Мне очень нравится Python. Но C # был задуман как статически явно типизированный язык, и так оно и должно быть. Нарушение правил для анонимных типов было достаточно плохо; Позволить людям пойти дальше и сломать идиомы языка еще больше - это то, что меня не устраивает. Теперь, когда джинна нет в бутылке, он никогда не вернется. C # будет балканизирован в лагеря. Фигово.
источник
Много раз во время тестирования я обнаруживал, что у меня есть такой код:
Теперь, иногда, я хочу посмотреть, что содержит само SomeOtherThing, SomeOtherThing не того типа, который возвращает CallMethod (). Так как я использую var, я просто изменяю это:
к этому:
Без var мне пришлось бы продолжать изменять объявленный тип также с левой стороны. Я знаю, что это незначительно, но это очень удобно.
источник
Для любителей, которые думают, что
var
экономит время, требуется меньше нажатий клавиш для ввода:чем
Считай их, если не веришь мне ...
19 против 21
Я объясню, если придется, но просто попробуйте ... (в зависимости от текущего состояния вашего интеллекта, возможно, вам придется набрать еще пару для каждого)
И это верно для каждого типа, о котором вы можете подумать !!
Мое личное мнение состоит в том, что никогда не следует использовать var, за исключением случаев, когда тип неизвестен, поскольку он уменьшает распознаваемость в коде. Мозгу требуется больше времени, чтобы распознать тип, чем полная строка. Старые таймеры, которые понимают машинный код и биты, точно знают, о чем я говорю. Мозг обрабатывает параллельно, и когда вы используете var, вы заставляете его сериализовать свой ввод. Почему кто-то хочет заставить свой мозг работать усерднее? Вот для чего компьютеры.
источник
Я раскол вар во всем места, только сомнительные места для меня являются внутренними короткими типами, например , я предпочитаю
int i = 3;
болееvar i = 3;
источник
Конечно, это может упростить ситуацию из кода, который я написал вчера:
Это было бы чрезвычайно многословно без
var
.Приложение: Небольшое время, проведенное с языком с реальным выводом типа (например, F #), покажет, насколько хороши компиляторы для получения правильного типа выражений. Это определенно означало, что я склонен использовать
var
столько, сколько я могу, и использование явного типа теперь указывает на то, что переменная не относится к типу инициализирующего выражения.источник
Нет, за исключением того, что вам не нужно писать имя типа дважды. http://msdn.microsoft.com/en-us/library/bb383973.aspx
источник