Почему 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 и т.д.

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

Ответ 1

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

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

или

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

Ответ 2

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

var obj = new SomeObject();

Если тип не очевиден, лучше написать его:

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

Ответ 3

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

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

Ответ 4

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

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

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

var value1 = GetNotObviousValue(); //What 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 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 использует его по умолчанию? Я бы предложил для удобства, потому что он не может разобрать нюансы ситуаций, чтобы решить, когда лучше не использовать его.

Ответ 5

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

ReSharper Options Menu

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

Turn off implicitly typed local variable suggestion

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

Ответ 6

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

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

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

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

Ответ 7

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

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

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

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

Ответ 8

"var" - это четкость

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

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

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

Кто пошел другим путем? Джейк или Билл? В этом случае использование имен "Jake" и "Bill" похоже на имя типа. И "Он" и "Его" похожи на ключевое слово 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 для него более полно для меня. Но я также склонен называть мои переменные после типа, поэтому я не теряю никакой информации.

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

Ответ 9

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

Ответ 10

Мое правило таково:

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

    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();
    

Ответ 11

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

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

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

Я объясню, как туда добраться.

В Visual Studio → Главное меню → Resharper → Параметры → Редактирование кода → С# → Стиль кода → Var Использование в объявлениях

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

введите описание изображения здесь

Ответ 12

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

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

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

Это просто сокращение, которое должно быть легче читать.

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

Ответ 13

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

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

Ответ 14

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

Ответ 15

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

var x = 1;

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

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

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

Ответ 16

Ключевое слово var было введено в С# 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

Ответ 17

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

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

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

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".: -)

Ответ 18

Для тех, кому не нравится постоянное использование "var":

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

Эти настройки находятся в разделе "Редактирование кода" → С# → Стиль кода

введите описание изображения здесь

Ответ 19

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

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

Ответ 20

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

Из своего сайта:

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

Ответ 21

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

Пример:

var s = "string value";

Очевидно, что s является a 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 = Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

Кроме этих сценариев, я не вижу никаких GAIN, которые могут быть сделаны с помощью 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.

Ответ 22

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

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

Менее типизировать var короче и легче читать, например

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

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

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

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

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

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

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

}

против

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

}

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