Использование ключевого слова var в C #

У меня была та же проблема на прошлой неделе, и я закончил писать плагин jQuery для этого.

Вот проект gitHub:

https://github.com / etienne-martin / mapify

Основное использование:

$("img[usemap]").mapify();

Пример в реальном времени

http://emartin.ca/ mapify /

406
задан 10 revs, 7 users 57% 3 February 2015 в 03:25
поделиться

81 ответ

Украденный от эти сообщение по этой проблеме в CodingHorror:

<час>

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

MyObject m = новый ();

Или если Вы передаете параметры:

Человек p = новый ("FirstName", "LastName);

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

В конце, это просто не было предназначено для сокращения дублирования. Не понимайте меня превратно, "var" ОЧЕНЬ важен в C# для анонимных типов/проекций, но использованием здесь является просто ПУТЬ прочь (и я говорил это в течение долгого, долгого времени), поскольку Вы запутываете тип, который используется. Необходимость ввести его дважды слишком часто, но объявление его обнуляет времена, лишь немногие.

Nicholas Paldino.NET/C# MVP 20 июня 2008 8:00

<час>

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

, Если Вы только идете в [1 117] когда-нибудь быть человеком, который смотрит на Ваш код, затем кто заботится? Иначе, в случае как это:

var people = Managers.People

это прекрасно, но в случае как это:

var fc = Factory.Run();

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

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

9
ответ дан 2 revs 3 February 2015 в 13:25
поделиться

Я использую var, когда это возможно.

фактический тип локальной переменной не должен иметь значения , если Ваш код правильно написан (т.е. хорошие имена переменной, комментарии, четкая структура и т.д.)

3
ответ дан Christian Klauser 3 February 2015 в 13:25
поделиться
  • 1
    @Heath: There' s ничто для экспериментирования о. It' s не возможный. That' s как наличие OP говорят " я хочу потянуть квадрат без краев " и мы говорим " Вы can' t." и Вы чувствуете, что мы должны позволить ему экспериментировать. (Который он все еще может, между прочим.), Что точно он должен сделать, и какой ответ Вы предпочли бы? Это - большой ответ в нем, даже указывает на другие ресурсы для обнаружения почему он can' t, от продвижения программистов на C++ не меньше. – GManNickG 13 July 2010 в 04:08

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

Если у вас есть строка кода, такая как

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

, ее читать намного легче или сложнее, чем:

var nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();
11
ответ дан 22 November 2019 в 23:33
поделиться

Думаю, это зависит от вашей точки зрения. У меня лично никогда не было проблем с пониманием фрагмента кода из-за var "неправильного использования", и мои коллеги и я часто его применяем. (Я согласен с тем, что Intellisense очень помогает в этом отношении.) Я приветствую его как способ избавиться от повторяющихся беспорядков.

В конце концов, если бы такие утверждения, как

var index = 5; // this is supposed to be bad

var firstEligibleObject = FetchSomething(); // oh no what type is it
                                            // i am going to die if i don't know

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

7
ответ дан 22 November 2019 в 23:33
поделиться

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

var content  = new Queue<Pair<Regex, Func<string, bool>>>();
...
foreach (var entry in content) { ... }

Это было бы чрезвычайно многословно без var .

Приложение: немного времени, потраченное на язык с выводом реального типа (например, F #) покажет, насколько хороши компиляторы для правильного определения типа выражений. Это определенно означало, что я стараюсь использовать var как можно чаще, а использование явного типа теперь указывает на то, что переменная не относится к типу инициализирующего выражения.

5
ответ дан 22 November 2019 в 23:33
поделиться

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

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);

Теперь, иногда, я хочу посмотреть, что содержится в самом SomeOtherThing, SomeOtherThing не того же типа что CallMethod () возвращает. Поскольку я использую var, я просто меняю это:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();

на это:

var something = myObject.SomeProperty.SomeOtherThing;

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

6
ответ дан 22 November 2019 в 23:33
поделиться

Скорее всего, это понадобится для анонимных типов (где это требуется на 100%); но это также позволяет избежать повторения в тривиальных случаях, а IMO делает линию более ясной. Мне не нужно видеть тип дважды для простой инициализации.

Например:

Dictionary<string, List<SomeComplexType<int>>> data = new Dictionary<string, List<SomeComplexType<int>>>();

(пожалуйста, не редактируйте hscroll выше - это вроде как подтверждает точку зрения !!!)

vs:

var data = new Dictionary<string, List<SomeComplexType<int>>>();

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

static void DoSomething(IFoo foo) {Console.WriteLine("working happily") }
static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");}

// this working code...
IFoo oldCode = new Foo();
DoSomething(oldCode);
// ...is **very** different to this code
var newCode = new Foo();
DoSomething(newCode);
27
ответ дан 22 November 2019 в 23:33
поделиться

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

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

...
List<MyClass> SomeMethod() { ... }
...

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

...
IList<MyClass> list = obj.SomeMethod();
foreach (MyClass c in list)
  System.Console.WriteLine(c.ToString());
...

. Если вы хотите провести рефакторинг SomeMethod () , чтобы вернуть IEnumerable , вам придется изменить объявление переменной (также внутри foreach ) везде, где вы использовали метод.

Если вместо этого вы напишете

...
var list = obj.SomeMethod();
foreach (var element in list)
  System.Console.WriteLine(element.ToString());
...

, вам не нужно его менять.

9
ответ дан 22 November 2019 в 23:33
поделиться

Нет, за исключением того, что вам не нужно писать имя типа дважды. http://msdn.microsoft.com/en-us/library/bb383973.aspx

5
ответ дан 22 November 2019 в 23:33
поделиться

Для любителей, которые думают, что var экономит время, для ввода требуется меньше нажатий клавиш:

StringBuilder sb = new StringBuilder();

, чем

var sb = new StringBuilder();

Подсчитать, если вы мне не верите ...

19 против 21

Я объясню, если нужно, но просто попробуйте ... (в зависимости от текущего состояния вашего интеллекта вам, возможно, придется ввести пару больше для каждого)

И это верно для всех типов, о которых вы можете подумать !!

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

6
ответ дан 22 November 2019 в 23:33
поделиться

Конечно, int - это просто, но когда тип переменной IEnumerable > , var делает все намного проще.

10
ответ дан 22 November 2019 в 23:33
поделиться

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

Хорошими причинами для использования ключевого слова var являются, например:

  • Там, где это необходимо, то есть для объявления ссылки для анонимного типа.
  • Где это делает код более читабельным, т.е. удаляет повторяющиеся объявления.

Запись типа данных часто упрощает выполнение кода. Он показывает, какие типы данных вы используете, поэтому вам не нужно выяснять тип данных, сначала выясняя, что делает код.

17
ответ дан 22 November 2019 в 23:33
поделиться

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

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

var variable = CallMe();

Это моя основная жалоба на var.

Я использую var, когда объявляю анонимные делегаты в методах, почему-то var выглядит чище, чем если бы я использовал Func . Рассмотрим этот код:

var callback = new Func<IntPtr, bool>(delegate(IntPtr hWnd) {
   ...
});

РЕДАКТИРОВАТЬ : обновлен последний пример кода на основе ввода Джулиана

39
ответ дан 22 November 2019 в 23:33
поделиться

Я использую var только тогда, когда ясно, какой тип используется.

Например, я бы использовал var в этом случае, потому что вы сразу видите, что x будет иметь тип «MyClass»:

var x = new MyClass();

Я бы НЕ использовал var в таких случаях, потому что вам нужно перетаскивать мышь по коду и просмотрите всплывающую подсказку, чтобы узнать, какой тип возвращает MyFunction:

var x = MyClass.MyFunction();

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

var x = 5;

(потому что компилятор не может знать, нужен ли мне байт, короткий, int или что-то еще)

7
ответ дан 22 November 2019 в 23:33
поделиться

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

С моей точки зрения, использование хороших соглашений об именах для переменных и методов более важно с точки зрения удобочитаемости, чем явная информация о типах. Если мне нужна информация о типе, я всегда могу навести курсор на переменную (в VS) и получить ее. Однако, как правило, читателю не требуется явная информация о типе.Для разработчика в VS вы по-прежнему получаете Intellisense, независимо от того, как объявлена ​​переменная. Сказав все это, все же могут быть случаи, когда имеет смысл явно объявить тип - возможно, у вас есть метод, который возвращает List , но вы хотите рассматривать его как IEnumerable в вашем методе. Чтобы гарантировать, что вы используете интерфейс, объявление переменной типа интерфейса может сделать это явным. Или, возможно, вы хотите объявить переменную без начального значения - потому что она сразу получает значение, основанное на каком-то условии. В этом случае вам нужен тип. Если информация о типе полезна или необходима, используйте ее. Однако я чувствую, что обычно в этом нет необходимости, и в большинстве случаев код легче читать без него.

118
ответ дан 22 November 2019 в 23:33
поделиться

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

  1. Тип анонимный (ну, здесь у вас нет выбора, поскольку он должен be var в данном случае)
  2. Тип очевиден на основе назначенного выражения (например, var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating () )

var не влияет на производительность, так как это синтаксический сахар ; компилятор определяет тип и определяет его после компиляции в IL; в нем нет ничего на самом деле динамического.

91
ответ дан 22 November 2019 в 23:33
поделиться

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

Является ли использование Intellisense ленивым? В нем меньше текста, чем в полном названии. Или есть вещи, которые требуют меньше работы, но не заслуживают критики? Я думаю, что есть, и var - один из них.

36
ответ дан 22 November 2019 в 23:33
поделиться

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

Я смотрю на эти критерии, когда решаю использовать var ]:

  • Тип переменной очевиден [для человека] из контекста
  • Точный тип переменной не особенно актуален [для человека]
    десятичное , строка , десятичное? , ...). Существует неявное предположение, что если вы используете var , должна быть «причина».

    Это все рекомендации. Вам также следует подумать об опыте и навыках ваших коллег, сложности алгоритма, долговечности / объеме переменной и т. Д. И т. Д.

    В большинстве случаев идеального правильного ответа не существует. Или это не имеет значения.

    В большинстве случаев нет идеального правильного ответа. Или это не имеет значения.

    В большинстве случаев нет идеального правильного ответа. Или это не имеет значения.

    [Изменить: удален повторяющийся маркер]

2
ответ дан 22 November 2019 в 23:33
поделиться

Вы можете позволить компилятору (и тому, кто обслуживает код следующим) определить тип из правой части присвоения инициализатора. Если такой вывод возможен, компилятор может это сделать, чтобы сэкономить на вводе текста с вашей стороны.

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

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

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

1
ответ дан 22 November 2019 в 23:33
поделиться

Иногда компилятор может также сделать вывод о том, что требуется, «лучше», чем разработчик - по крайней мере, разработчик, который не понимает, что требуется для используемого API.

Например, при использовании linq :

Пример 1

Func<Person, bool> predicate = (i) => i.Id < 10;
IEnumerable<Person> result = table.Where(predicate);

Пример 2

var predicate = (Person i) => i.Id < 10;
var result = table.Where(predicate);

В приведенном выше коде - при условии, что используется Linq to Nhibernate или Linq to SQL, Пример 1 будет вернуть весь набор результатов для объектов Person, а затем выполнить фильтрацию на стороне клиента. Однако в примере 2 запрос будет выполняться на сервере (например, на сервере Sql с SQL), поскольку компилятор достаточно умен, чтобы определить, что функция Where должна принимать Expression>, а не Func.

Результат в примере 1 также не будет запрашиваться на сервере, поскольку возвращается IEnumerable, тогда как в примере 2 компилятор может решить, должен ли результат быть скорее IQueryable вместо IEnumerable

1
ответ дан 22 November 2019 в 23:33
поделиться

Это просто удобство. Компилятор определит тип (на основе типа выражения в правой части)

3
ответ дан 22 November 2019 в 23:33
поделиться

В большинстве случаев набрать его проще - представьте

var sb = new StringBuilder();

вместо:

StringBuilder sb = new StringBuilder();

Иногда это требуется, например: анонимные типы, например.

var stuff = new { Name = "Me", Age = 20 };

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

5
ответ дан 22 November 2019 в 23:33
поделиться

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

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

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

Он скрывает намерение и по крайней мере в одном случае приводит к ошибке времени выполнения в некотором коде из-за предположения о типе.

5
ответ дан 22 November 2019 в 23:33
поделиться

В результате обсуждения этой темы результат выглядит следующим образом:

Хорошо: var customers = new List ();

Спорный: var customers = dataAccess.GetCustomers ();

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

Подумайте:

IList<Customer> customers = dataAccess.GetCustomers();

var dummyCustomer = new Customer();
customers.Add(dummyCustomer);

Теперь рассмотрите:

var customers = dataAccess.GetCustomers();

var dummyCustomer = new Customer();
customers.Add(dummyCustomer);

Теперь перейдите и реорганизуйте класс доступа к данным, чтобы GetCustomers возвращал IEnumerable , и посмотрите, что произойдет ...

проблема здесь в том, что в первом примере вы явно выражаете свои ожидания от метода GetCustomers - вы ' говорят, что вы ожидаете, что он вернет что-то, что ведет себя как список. Во втором примере это ожидание неявно и не очевидно сразу из кода.

Интересно (для меня), что многие аргументы pro-var говорят: «Мне все равно, какой тип он возвращает», но чтобы сказать: «Мне просто нужно перебрать это ...». (поэтому необходимо реализовать интерфейс IEnumerable, подразумевая, что тип имеет значение ).

3
ответ дан 22 November 2019 в 23:33
поделиться

Удивительно, что это не было отмечено до сих пор, но это здравый смысл - использовать var для foreach переменных цикла.

Если вы вместо этого укажете конкретный тип, вы рискуете тем, что компилятор молча вставит в вашу программу приведение во время выполнения!

foreach (Derived d in listOfBase)
{

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

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

2
ответ дан 22 November 2019 в 23:33
поделиться

var - это заполнитель, введенный для анонимных типов в C # 3.0 и LINQ.

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

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

Это особенно полезно, когда даже с IntelliSense имя типа длинное для ввода.Просто напишите var и создайте его экземпляр. Другие программисты, которые после прочтут ваш код, легко поймут, что вы делаете.

Это похоже на использование

public object SomeObject { get; set; }

вместо:

public object SomeObject {
    get {
        return _someObject;
    } 
    set {
        _someObject = value;
    }
}
private object _someObject;

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

2
ответ дан 22 November 2019 в 23:33
поделиться

Я думаю, что вы можете неправильно понимать использование var в C #. Это по-прежнему строгая типизация, в отличие от типа VB varient, поэтому его использование или отсутствие не влияет на производительность.

Поскольку это не влияет на окончательный скомпилированный код, это действительно выбор стилиста. Лично я не использую его, поскольку считаю, что код легче читать с определенными полными типами, но я могу представить, что через пару лет объявление полного типа будет рассматриваться так же, как сейчас венгерская нотация - лишний набор текста без реальной выгоды по сравнению с информацией, которую intellisense предоставляет нам по умолчанию.

2
ответ дан 22 November 2019 в 23:33
поделиться

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

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

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

С учетом сказанного, я предпочитаю использовать var alot, если тип более сложный и / или он явно повторяется в правой части присваивания. Это может быть List или т. Д., Например:

var list = new List<string>();

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

Вкратце, я делаю следующее:

  • Назовите тип явно, если тип короткий или не может быть прочитан вне контекста
  • Используйте var, когда его нужно использовать (да)
  • Используйте var, чтобы лениться, когда это (на мой взгляд) не ухудшает читабельность
3
ответ дан 22 November 2019 в 23:33
поделиться

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

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

1
ответ дан 22 November 2019 в 23:33
поделиться

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

2
ответ дан 22 November 2019 в 23:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: