Реклама
Комментарии 57
Мы пока на работе используем 2005 студию и, хотя сам я и использую 2008, но приходится следить за совместимостью, поэтому var`ом не пользуюсь, как и другими прелестями C# 3.0.
Для таких типов как int, double, decimal, string не вижу особого смысла использовать var (Это только путает), а вот при использовании new, удобство конечно ощутимое. Намного понятнее смотрится «var list = new List
Смысл для стандартных типов есть в виде 2 и 4 пункта: грамотное именование и обязательная инициализация. С другой стороны, ничего не мешает именовать и инициализировать тот же string самому и без var. Похоже, в этом случае смысл больше в философии, чем в конечной пользе.
2 пункт: Я и так всегда стараюсь использовать подробные имена.
4 пункт: Это вообще спорный вопрос. Я в ASP.NET`е часто использую конструкции вида:
int value;
try { value = Convert.ToInt32(...); } catch { return null; }
Если мне нужно объявить переменную без инициализации, почему бы мне это не сделать.

Просто запись var value = 5; для меня неудобна. Я понимаю, что 5 имеет тип int, но тут нигде это не указано. поэтому тут я предпочту int value = 5;
между прочим, использование перехвата исключений очень неоптимально для конвертирования в int
почему бы не использовать придуманный для этих целей Int32.TryParse()?

по делу, я в целом с вами согласен, но очевидно, что в словах Ильи Ряженкова тоже есть доля смысла
Тут скорее дело вкуса. Главное, чтобы каждый потом сам разобрался в своём коде.

По поводу TryParse, я учту. Я пока только учусь: о)

если учитесь, то совет: старайтесь минимизировать использование исключений, особенно в таких банальных вещах
Вопрос спорный, согласен. Лично я это правило в решарпере отключил и не использую вар для простых типов, а пользуюсь в редко, тк в противном случае код становится менее читаемым.
в этой статье, в том числе, написано, как с var добиться столь же читаемого кода, как и без var
впрочем, я так же редко использую var, правда, теперь появилось желанее использовать его больше
Практически всегда и везде использую var — это банально удобно.
В особенности при обьявлении типа
var list = new List<IMySuperPuperInterface>();
Зачем читать то, что уже написано?

Часто я банально не помню что возвращает тот или иной метод. Помню что что-то енумерабильное, причем какого-то конкретного типа, а какое — фиг знает.
Если обьявлю переменную как IEnumerable, то рискую забыть про какой-то функционал, и в результате тип переменной придется сначала посмотреть, потом переопределить. С вар все проще, будет использовано ровно то, что есть.

Про имена вопрос философский, имхо изменилось при использовании вара немного. Как были имена, так они и остались.

Вот в целом чем мне кажется полезным var, поэтому его и использую.
К конструкция типа
var sum = 0; var text = "Hello, world!";
уже привык. Мозг не страдает.
Использование var я считаю большим преимуществом уже только ради пятого пункта. Шума меньше в разы. Читать заметно проще.
var превращает C# в питон :)
хотя я пока ещё не писал на 3-м шарпе, мне кажется что повсеместное использование var — это плохо.

вот, например, как будет компилироваться такой код?

var currentItemValue = «»;


currentItemValue = 5;

будет ли ошибка? будет ли число приведено к строке? или изменится тип переменной (как в питоне или руби)?

в данном случае явное объявление string currentItemValue лучше.
не уверен про питон, но компилятор C# определит при инициализации currentItemValue как string и currentItemValue = 5;
вызовет ошибку компиляции. Программа даже не запустится. В C# var — это просто способ скрыть название типа тогда когда это имеет смысл.
вот, значит будет ошибка.
неинтуитивно :) а в комплекте с начинающими программистами это способно вызвать очень много ошибок.
почему неинтуитивно?

это

string currentItemValue = «»;


currentItemValue = 5;

интуитивнее? кстати, если вы читали эту статью, то поняли бы что в связке с var переменную следует называть currentItemTextValue
где-то была статья, что не стоит городить огромные имена переменны. код станет ещё стращнее чем без var
var в C# — это совершенно НЕ тип variant, который есть в некоторых языках
Var ничего общего с поздним связыванием не имеет. А начинающий программист вряд ли ожидает такой возможности. Тем более, что подобного рода ошибки выявляются на этапе компиляции. Проблем быть не должно.
Resharper страшно тормозил всю систему оба раза которые я его ставил на протяжении последних 4 лет. После чего я им не пользуюсь, думаю что от использования var вместо явно подходящих для конкретного случая типа приведёт к тому же эффекту — замедлению исполнения кода.

C# — это всё таки Си, не надо делать из него Бейсик.
Насколько я понял, к замедлению исполнения кода это не должно привести. Все типы выводятся на этапе компиляции. Однако, хотя я еще и не писал на C# 3.0, читать код с использованием var мне, честно говоря, пока трудновато.
Просто картина становится похожа на javascript, с точки зрения читаемости кода.
ну все хорошо в меру, плохому программисту и var не надо чтобы все запутать
тезисы этой статьи ясно показывают почему var полезен в C#, сравнение с другими языками вообще считаю неуместным
Resharper в 4 версии шагнул далеко вперед по производительности.
Илья очень просит изменить написание его фамилии, правильно будет: Рыженков.
Заранее спасибо!
сорри, исправил
а вы знакомы с Ильей? А может быть он появится на Хабре, я думаю было бы интересно как почитать его статьи так и пообщаться
Мы всегда рады пообщаться с нашими пользователями тут: www.intellij.net/forums/category.jspa? categoryID=6

К сожалению, просто не хватает времени быть везде. Но мы стараемся читать все, что пишут про нас в интернете и по возможности отвечать.
Доводы нормальные, но надо понимать, что в Microsoft тоже не глупые люди работают, и если они что-то рекомендуют (или не рекомендуют) в отношении использования ИХ инструментов, то лучше прислушаться именно к ним.
Уверен, доводов у Microsoft не меньше, тот же Кшиштоф Квалина часто разбирает подобные спорные моменты.
и именно поэтому в C# 4.0 будет late bound.

разницы между декларацией со специфицированным типом и var нет никакой. это всего лишь вопрос поддержки кода, т.е. опыта и интеллекта.
Не знаю, с одной стороны все эти аргументы правильные. Но если взглянуть по другому, то правильные имена переменным и без того нужно давать внятные, инициализировать переменные и т.д. (хотя, как писали уже раньше, не всегда это и нужно).

Включать имя класса, который возвращает функция в её название не всегда является возможным(бывают и без того длинные имена, да и как можно будет правильно обозвать какую нить типизированую коллекцию в имени ф-ии?). Как раз мне кажется такие длинные имена только добавят «шума» в код, так как все это прийдется читать, а не выхватывать просто взглядом.

Насчет шума в коде при объявлении переменных — это дело привычки мне это абсолютно не мешает, так как чтобы увидеть тип переменной, я смотрю на её объявления, а не инициализацию. Но опять же, это привычка, поэтому за правило не прокатит :)

«Уменьшить использование директивы using» — это вообще непонятно зачем, кому они мешают? Я вот сейчас разбираюсь с крупными проектами, написанными до меня, так там открывая незнакомый класс, я останавливаю взгляд на этих самых директивах, чтобы нормально понимать с чем мне предстоит работать в этом классе.

Ещё сходу пример по этому поводу. Я, предположим, увидел следующий код:

var products = someDB.GetProducts();

Я логически конечно могу догадаться что возвращает этот метод, но только в общем. Какие же классы конкретно для этого используются — не поймешь. Если бы было так:

IQuerable<Product> products = someDB.GetProducts();

Я бы сразу понял, что имею дело с IQuerable, и при желании без проблем щелкнул бы по «Product» правой кнопкой, Go to definition и наслаждаюсь разбором замысловатого класса Product. Согласитесь, что var все же совсем не облегчает эту работу.

Если резюмировать, то я склонен четко называть имена переменных и использовать var в 99% случаев только с анонимными типами. Автор этих доводов, бесспорно, опытный человек, но некоторые пункты притянуты зауши, имхо, чтобы было больше пунктов (как с using, например).

PS. Сори за многобуков, и небольшой сумбур в изложении.
Согласен, var хоть и удобная, но весьма вредная «привычка». Не тот язык C# чтобы засорять его подобными фенечками. С# прост и прямолинеен — как танк. А танку «бантики» не нужны :)

PS: Безусловно, для анонимных типов var необходим, но не более того.
Мне кажется твоя и Ильи точки зрения просто параллельны друг другу, то есть не мешают. На практике можно брать чуток из одной, чуток из другой. Мне понятна и та и другая. До того, как я прочитал эту статью, у меня на видение проблемы была только одна точка зрения — «var» использовать пореже. Теперь в сознании появилось разнообразие.
Не мешают они до тех пор, пока он «там» себе что-то пишет, а я «здесь». А если бы мы в одной компании работали? :)

За примером даже далеко ходить не нужно. Взять кусочек кода в самом конце статьи о Expression Trees, там где замеры делаются. Вот мне этот элементарный код не очевиден, я его не могу просто одним взглядом прочесть, что куда присваивается, что возвращается и т.д. Хотя примеров на C# я уже перечитал достаточно, чтобы набить руку и сходу понимать. Даже в цикле for и то var написано. В тоже время если бы <~legigor> читал мой код — ему бы «рябило».

Так что эти два стиля программирования вполне могут быть и сосуществовать, пока их пользователи не пересекаются :)
для компаний естественным выбором является написание внутреннего (или принятие какого-то существующего) соглашения об оформлении кода и тогда таких проблем как правило не возникает
Тому кто позже в неё попадет — придется ломать стереотипы ))
к сожалению, к компаниях, иной раз, сложнее поломать другие стереотипы типа дрескода или корпоративной этики
Вот простой пример кода, когда тип не является анонимным, но явно его указать нельзя.

class A<T>
{
 T myField;

 void Foo<T>(T p)
 {
  var v = myField;
 }
}

* This source code was highlighted with Source Code Highlighter.


А «var» будет и в новом C++ — в языке концептуально более строгом.
может я чего то не понял, но что мешает написать:

void Foo(T p)
{
T v = myField;
}
угловые скобки пропали, как понимаю, и в вашем и в моем варианте.

тогда наверное стоит тип в определении шаблонного метода называть не T
Код работать не будет. Скажет, что-то в духе «не понимаю, какой нахер T»?
Т понятно какой, из декларации метода, но ожидается как раз Т из декларации класса.
Да, именно так и говорит.

Народ тут спорит о самых тонкостях правильно или нет использовать var, но, согласитесь, за такой код как вы в примере написали, нужно бить по пальцам.
Если var counter = 25; может быть и не очевидно, то такая путаница типов вообще страшно выглядит.

Разрешение ошибки компилятора в данном случае с помощью var — вообще как баг выглядит, и его как аргумент приводить неправильно.
на самом деле все это религиозные войны

со своей стороны могу несколько доводов в пользу var привести:

1) Зачастую важен не тип, а его содержание, а Go to type declaration работает и на var и не на var
2) Зачастую важен не тип, а семантика — а это уже задача грамотно написанного локального кода, хороших имен методов и проч.
3) var спасет от головной боли в случае массовых рефакторингов и изменений в иерархиях типов
4) вы все равно полагаетесь на компилятор в плане проверки типов, пусть он еще и выводит их, заодно будет работать комплишн (актуально если декларация сужает возвращаемый тип)

а counter не бывает типа string, так что var counter очевидность не снижает
и главное, что строчки с var чудом влезают по ширине в экран монитора — вот за это уже можно отдать все, и черт с ними, остальными пунктами!
Warning 2 Type parameter 'T' has the same name as the type parameter from outer type 'A'
Это ли не повод задуматься?:)
конечно повод :)
но в большом проекте обычно столько варнингов!
опять же, если код, например, автогениренный, то никто даже не обратит внимания.
вар очень хорош для уменьшения шума в коде, но, конечно, применять его надо с умом :) в общем то, нет смысла спорить о варе, потому что, если только заменять обычное определение типов, на процесс исполнения это не влияет, определяющим здесь является стиль программиста ) а еще очень интересно, нет ли у Микрософта стилистических рекомендаций по написанию кода для 3.0?
Ещё случай, когда var предпочтительней:

Пусть есть ASP.NET Web Site, в нём подпапка SomeFolder, в ней — папка Controls, в ней контрол UserPreview.ascx. Имя класса для этого контрола будет иметь вид: SomeFolder_Controls_UserPreview.

И где-нибудь в обработчике события ItemDataBound (у Repeater-a, например) при получении ссылок на эти User-контролы внутри ItemTemplate мы напишем:

var userProfile = (SomeFolder_Controls_UserPreview)e.Item.FindControl(«userProfile»);

Дублировать тут это длинное автогенерируемое имя дважды — явный шум.

Ну а с другой стороны:
int usersCount = 0;
немного предпочтительнее всё же, чем
var usersCount = 0;

Все остальные случаи — где-то между.
не спорю :) там просто конкретизировано про generics, а я тут немного из другой сферы решил добавить
Хороший пример, когда бездумное применение var приводит к косякам:

var anObj = new SomeComponent();
Assert.Taht(anObj.Property1, Is.True);

вместо явного указания такого плана

ISomeComponent anObj = new SomeComponent();
Assert.Taht(anObj.Property1, Is.True);
Только полноправные пользователи могут оставлять комментарии. , пожалуйста.