Какой смысл в ключевом слове var? - PullRequest
44 голосов
/ 16 октября 2008

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

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

Что заставляет меня задуматься, почему разработчики языка C # вообще пытались включить ключевое слово var?

Обновление : Да, var поддерживает анонимные типы, но сами по себе анонимные типы не требуют ключевого слова var ...

var anon = new { Name = "Terry", Age = 34 };

против

anon = new { Name = "Terry", Age = 34 };

Ответы [ 8 ]

47 голосов
/ 16 октября 2008

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

name = "fred";
   ...
Name = "barney"; // whoops! we meant to reuse name
45 голосов
/ 16 октября 2008

Обновление: Здесь на самом деле есть два связанных вопроса: 1. Почему я должен объявлять переменные вообще? 2. Что такое «var» в языке, который заставляет вас объявлять переменные?

Ответы на (1) многочисленны и могут быть найдены в других местах для этого вопроса. Мой ответ на (2) ниже:

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

SomeGeneric<VeryLongTypename<NestedTypename>> thing = new   
SomeGeneric<VeryLongTypename<NestedTypename>>();

Подробно и подвержено ошибкам, верно? Так что теперь они позволяют вам сделать это:

var thing = new SomeGeneric<VeryLongTypename<NestedTypename>>();

За счет уменьшения дублирования информации устраняются ошибки. Обратите внимание, что здесь не просто ошибки ввода: возможно, что тип левого выражения может быть напечатан с ошибкой таким образом, что компилятор может выполнить бесшумное приведение слева направо, но приведение фактически теряет некоторое свойство Rvalue. Это еще более важно, когда типы, возвращаемые значением rvalue, могут быть неизвестными или анонимными.

39 голосов
/ 30 апреля 2009

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

Почти в каждом примере .net 3.5, который я вижу в последнее время, все переменные определены с помощью var.

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

// What myVar is, is obvious
SomeObject myVar = new SomeObject();

// What myVar is, is obvious here as well
var myVar = new SomeObject();

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

// WTF is var without really knowing what GetData() returns?
// Now the var shortcut is making me look somewhere else when this should
// just be readable!
var myVar = GetData();

// If the developer would have just done it explicitly it would actually
// be easily readable.
SomeObject myVar = GetData();

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

var weight = GetExactWeightOfTheBrownYakInKilograms();

Все еще не знаю, что возвращается. Это объект типа int, decimal, float, weight, что? Мне все еще приходится тратить время на поиски ... нужен костяк intellisense, чтобы спасти день от ленивого программирования. Может быть, включить тип возвращаемого значения в имя функции. Хорошая идея, теперь использование var не спасло нас ничего, кроме того, что все мои функции получили настоящие длинные имена.

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

5 голосов
/ 16 октября 2008

Это немного субъективно, но я думаю, что разработка C # 3.0 с ключевым словом «var» для неявно типизированных переменных вместо ключевого слова делает код более читабельным. Например, первый блок кода ниже более читабелен, чем второй:

Очевидно, где объявлена ​​переменная:

var myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;

Не очевидно, где объявлена ​​переменная:

myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;

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

4 голосов
/ 16 октября 2008

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

Например, в разделе обновления вашего вопроса вы спрашивали об этом фрагменте:

anon = new { Name = "Terry", Age = 34 };

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

Ваш ответ таков: Бу это делает, поэтому все должно быть в порядке или, по крайней мере, возможно. Но это красная сельдь. Мы говорим о C #, а не о Boo. Одна из целей C # - иметь язык, на котором компилятор может отлавливать столько ошибок, сколько возможно. Бу тоже хочет это сделать, но также хочет быть похожим на Python. Таким образом, он жертвует некоторыми (не всеми) безопасностью C # во время компиляции в обмен на Python-подобный синтаксис.

1 голос
/ 16 октября 2008

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

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

bill=5;
bi11=bill+5

Какова стоимость счета?

Тем не менее, я нахожу несколько раздражающим время от времени набирать:

DataOutputStream ds=new DataOutputStream();

Кажется излишним, но, честно говоря, в этом нет ничего плохого. Это не займет больше времени, чтобы набрать его дважды, и это очень полезно. Что занимает время, так это когда у вас есть вопросы - когда вы не уверены, как использовать какой-то API. Если вам действительно надо дважды вводить это объявление типа, то почему вы тратите свое время здесь? Поскольку вы начали читать это, вы могли набрать 30 или 40 деклараций, что достаточно для каждой декларации, которая понадобится вам в течение следующих двух недель.

Полагаю, я говорю, что, хотя я понимаю эмоциональное напряжение, которое может вызывать повторение, последовательность, ясность и способность создавать более интеллектуальные инструменты делают это ХОРОШИМ.

Еще одна вещь, в большинстве случаев код не должен быть похож на мой пример выше. Что вы должны делать, это:

DataOutput ds=new DataOutputStream();

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

0 голосов
/ 16 октября 2008

Для анонимных типов, которые помимо прочего поддерживают LINQ.

http://www.blackwasp.co.uk/CSharpAnonTypes.aspx

0 голосов
/ 16 октября 2008

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

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

Анонимные типы могут использоваться в других местах, кроме Linq.

var чрезвычайно полезен для Linq. На самом деле, по словам одного эксперта-автора, « без« var », LINQ становится слишком болезненным для использования.

...