Почему ReSharper хочет использовать "var" для всего?

Я только начал использовать ReSharper с Visual Studio (после многих рекомендаций по SO). Чтобы попробовать, я открыл недавний ASP.NET проект MVC. Одна из первых и наиболее частых вещей, которые я заметил, - это изменить большинство/все мои явные объявления на var вместо. Например:

//From This:
MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
//To This:
var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

и так далее, даже с простыми типами, такими как int, bool, etc.

Почему это не рекомендуется? Я не из компьютерной науки или .NET Предыстория," попав " в разработку .NET в последнее время, поэтому я бы очень хотел понять, что происходит и приносит ли это пользу или нет.

22 ответов


одна из причин-улучшение читаемости. Что лучше?

Dictionary<int, MyLongNamedObject> dictionary = new Dictionary<int, MyLongNamedObject>();

или

var dictionary = new Dictionary<int, MyLongNamedObject>();

то, что предлагает ReSharper, явно злоупотребляет ключевым словом var. Вы можете использовать его там, где тип очевиден:

var obj = new SomeObject();

Если тип не очевиден, вы должны скорее записать его:

SomeObject obj = DB.SomeClass.GetObject(42);

Я лично предпочитаю отключить это предложение. Используя var часто может улучшить читаемость; но, как вы упомянули, он иногда уменьшает его (с простыми типами или когда результирующий тип непонятных).

Я предпочитаю выбирать, когда я использую var и когда я этого не делаю. Но опять же, это только я.


var смогите увеличить считываемость кода пока уменьшающ немедленное понимание кода. Точно так же, это может уменьшить читаемость кода для других ситуаций. Иногда его использование нейтрально. Мера читаемости для понимания не пропорциональна, но зависит от ситуации. Иногда оба увеличиваются и уменьшаются вместе.

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

например, плохое именование может привести к var вызывает снижение понимания кода. Это не var ошибка хотя:

var value1 = GetNotObviousValue(); //What's the data type? 
//vs. 
var value2 = Math.Abs(-3); // Obviously a numeric data type. 

иногда не имеет смысла использовать var для простых типов данных, когда код более читаем в его отсутствие:

var num = GetNumber(); // But what type of number?
// vs. 
double num = GetNumber(); // I see, it's a double type. 

иногда var может быть полезно скрыть информацию о типе данных, которую вы не обязательно обратите внимание на сложности:

    IEnumerable<KeyValuePair<string,List<Dictionary<int,bool>>>> q = from t in d where t.Key == null select t; // OMG! 
    //vs. 
    var q = from t in d where t.Key == null select t;

    // I simply want the first string, so the last version seems fine.  
    q.First().Key; 

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

var o = new { Num=3, Name="" };

когда Visual Studio Intellisense предоставляет сведения о типе, несмотря на var, вам тогда нужно меньше полагаться на свое понимание через строгое чтение кода без помощи. Вероятно, разумно предположить, что не все могут иметь или использовать Intellisense.

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

почему Resharper использует его по умолчанию? Я бы предложил для удобства, потому что он не может анализировать нюансы ситуаций, чтобы решить, когда лучше не использовать его.


в ReSharper (8.02, но, вероятно, другие версии), опция для предложения "использовать неявно типизированное объявление локальной переменной" может быть скорректирована на ваш предпочтения, что бы это ни было, сначала откройте меню опций для ReSharper:

ReSharper Options Menu

затем, в разделе "Проверка кода", регулируя" серьезность проверки " выбранного вами языка, в моем случае c#:

Turn off implicitly typed local variable suggestion

Как вы можете видеть, есть варианты отрегулируйте все предложения, которые делает ReSharper. Надеется, что это поможет кому-то вроде меня, у кого уже есть стратегия использования " var " и просто хочет, чтобы ReSharper уважал его :)


Я удивлен, что никто не упомянул, что также легче изменить тип экземпляра объекта, потому что

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

- это форма повторения. Если я хочу измениться AVeryLongTypeName в один из его производных классов мне нужно изменить только один раз при использовании var и все еще может получить доступ к методам дочерних классов.

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


' var ' о том, чтобы быть ясным

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

просто, как если бы вы писали историю, нет окончательного правильного ответа. Но давайте рассмотрим некоторые примеры этого на простом английском языке.

кто в другую сторону? Джейк или Билл? В этом случае использование имен "Джейк" и "Билл" похоже на использование имени типа. И "он", и " он " - это как использовать var ключевое слово. В этом случае было бы полезно уточнить. Следующее, например, гораздо яснее.

в этом случае более конкретное предложение стало более ясным. Но так будет не всегда. случай. В некоторых случаях конкретность затрудняет чтение.

в этом случае было бы легче прочитать предложение, если бы мы использовали " он " и в некоторых случаях опустили его имя все вместе, что эквивалентно использованию var ключевое слово.

Билл любит книги, поэтому он пошел в библиотеку и взял книгу, которую он всегда нравилось.

эти примеры охватывают суть, но они не рассказать всю историю. В этих примерах есть только один способ обратиться к человеку. Либо используя их имя, либо используя более общий термин, как "он" и "его".

в случае кода у нас есть 3 способа помочь добавить ясность. Тип, имя переменной, и назначение. Возьмите эту строку кода, например:

Person p = GetPerson();

теперь возникает вопрос, достаточно ли информация в этой строке кода поможет вам понять, что происходит?

как насчет следующей строки кода? Вы все равно знаете, что p означает в данном случае:

var p = GetPerson();

вот так:

var p = Get();

или так:

var person = Get();

или такой:

var t = GetPerson();

или такой:

var u = Person.Get();

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

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

что сказал Иногда в зависимости от контекста я делаю исключения, такова природа чего-либо сложного, и программное обеспечение ничего, если нет сложный.


мне это тоже не понравилось.

Я не хочу, чтобы это превратилось в дебаты на использовании var, Он имеет свои пользы но не должен быть использован везде.

главное, что нужно помнить, - ReSharper настроен на любые стандарты кодирования, которые вы хотите.

изменить: ReSharper и var


мое правило это:

  • вы объявляете примитивный тип (т. е. byte, char, string, int[], double?, decimal, etc.)? - >Используйте тип:

    string myStr = "foo";
    int[] myIntArray = [123, 456, 789];
    double? myDouble = 123.3;
    
  • вы объявляете сложный тип (т. е. List<T>, Dictionary<T, T>, MyObj)? -> Использовать var:

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();
    

Я просто хотел бы указать, что использование " var " рекомендуется в Соглашения Кодирования C# "когда тип переменной очевиден с правой стороны назначения или когда точный тип не важен", так что, вероятно, поэтому подсказка по умолчанию включена в ReSharper. Они также предоставляют некоторые случаи, когда это не улучшило бы читаемость прямо ниже в том же документе.


Я вижу много правильных ответов, но не хватает полной.

верно, что Resharper по умолчанию использует var. Думаю, большинство согласится с этим. Также легче читать, когда используется var, и тип очевиден, например, при использовании нового оператора. Я видел один пост, который показал, как обновить серьезность проверки, чтобы показывать только подсказки для использования var.

Я попытался прокомментировать другие сообщения, чтобы добавить, где их установить, но не имел репутация за это. По-видимому, у меня также не было репутации, чтобы опубликовать мой скриншот настроек.

Мне придется объяснить, как туда добраться.

в Visual Studio - > главное меню - > Resharper - > параметры - > редактирование кода - > C# - > стиль кода - > использование Var в объявлениях

  • для встроенных типов явное типа
  • для простых типов используйте "var", когда очевидно
  • в другом месте Используйте бульвар'

enter image description here


ReSharper рекомендует var, потому что он имеет тенденцию к созданию объекта unclutter.

сравните эти два примера:

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

это просто стенография, которую, как предполагается, легче читать.

Я думаю, что это нормально, когда вы создаете новые объекты явно с помощью "new". Однако в вашем примере это может быть не очевидно, если классы не были названы правильно.


кстати, ReSharper проводит различие между "Вы можете применить это предложение к вашему коду" и " ваш код сломан, хотите, чтобы я его исправил?'. The var ключевое слово находится в категории предложений вместе с такими вещами, как "инвертировать, если уменьшить вложенность"; вам не нужно следовать ему.

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


на var особенность .Net 3.0-это просто определение типа, который является безопасным типом и часто упрощает чтение вашего кода. Но вам не нужно, и вы можете отключить эту рекомендацию в resharper, если хотите.


технической разницы нет, если вы используете var, тип подразумевается компилятором. Если у вас есть такой код:

var x = 1;

x подразумевается как int, и никакие другие значения не могут быть назначены ему.

ключевое слово var полезно, если вы меняете тип переменной; вам нужно сделать только одно изменение вместо двух:

var x = 1; --> var x = "hello";
int x = 1; --> string x = "hello";

на var ключевое слово было введено в C# 3.0 - это позволяет нам забыть о нашей явного указания типа.

нет никакой реальной разницы, используете ли вы

MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

или

var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

за исключением чистой читаемости и меньше шансов на ошибку.

это похоже на клише пример, но сказать следующее может помочь вашему пониманию:

var myInt = 23;

возвращает int тип, тогда как

var myInt = "23";

возвращает string тип.

MSDN reference


указание явного типа объекта как-то избыточно. Даже в переводе на английский язык это звучит избыточно:" поместите объект типа X в переменную типа X "vs"поместите объект типа X в переменную".

однако использование 'var' имеет свой ограничения. Это предотвращает использование ниже полиморфизм что это красота:

предположим, что собака расширяет животное; кошка расширяет класс животных иерархия:

Animal x = new Dog();
DoStuffWithDog(x as Dog);

x = new Cat();
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

тот же код, с X, объявленным с 'var'не будет компилироваться.

var x = new Dog(); // from this point, x is a Dog
DoStuffWithDog(x as Dog);

x = new Cat(); // cannot assign a Cat instance to a Dog
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

в любом случае, вернемся к исходному вопросу, я не использую Resharper, но я предполагаю, что это достаточно умно, чтобы обнаружить, когда не использовать "var". :-)


Var удивительно! Я столкнулся со многими разработчиками, которые находятся под впечатлением, что var привязан к динамическому типу, это не так. Он все еще статически типизирован, это просто решил компилятор.

вот некоторые удивительные плюсы использования var

меньше набирать var короче и легче читать, например

Dictionary<int,IList<string>> postcodes = new Dictionary<int,IList<string>>() ЮК.

var postcodes = new Dictionary<int,IList<string>>() \o / \o/

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

меньше изменений в коде - если тип возврата вызова метода изменяется. Вам нужно только изменить вызов метода, а не каждое место, где он используется.

анонимные типы - анонимные типы-действительно мощная концепция, особенно в таких областях, как WebApi частичное ресурсов. Без var их нельзя использовать.

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

for(var i = 0; i < 10; i++) 
{

}

vs

for(int i = 0; i < 10; i++) 
{

}

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


для тех, кто не любит постоянное использование "var":

Примечание: Вы также можете остановить resharper от дефолта до var при выполнении "ввести переменную". Это было что-то, что расстраивало меня в течение долгого времени, это всегда было дефолтом var, и я менял его каждый раз.

эти настройки находятся под редактированием кода --> C# --> стиль кода

enter image description here


на мой взгляд, var должны использоваться только тогда, когда сразу ясно, что этот тип при определении значения переменной.

пример:

var s = "string value";

очевидно, что s это string.

Я считаю, что это также уместно, когда имя типа переменной очень сложное.

пример:

Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>> dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

// This is a little easier to read than the above statement
var dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

кроме этих сценариев, я не вижу никакой выгоды от использования var, но я могу придумать несколько сценариев, в которых это может быть вредно:

например, одноразовый тип, значение правой переменной которого четко не показывает тип. Избавление от IDisposable можно легко забыть о

пример:

// returns some file writer
var wr = GetWriter();

wr.add("stuff");
wr.add("more stuff");

//...
//...

// Now `wr` needs to be disposed, 
// but there is no clear indication of the type of `wr`,
// so it will be easily overlooked by code writer and code reviewer.

нет никакой технической разницы (как указал eWolf). Вы можете использовать один или другой, сгенерированный код CLR будет выглядеть так же.

на мой взгляд, основное преимущество заключается в том, что это ведет к использованию более именования переменных. В вашем примере " foo " - довольно плохой выбор для имени переменной.


согласно JetBrains (автор ReSharper), они поощряют использование var по умолчанию.

из них сайт:

использование неявно типизированных локальных переменных (также известных как ключевое слово var), введенных в C# 3.0, стало довольно популярным из-за улучшенной читаемости полученного кода. По умолчанию ReSharper также поощряет использование ключевого слова var, но предпочтения его использования гибко настраиваются. Например, вы можете выбрать использование явных типов в определенных случаях или везде.