Какая точка ключевого слова var?

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

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

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

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

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

против

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

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

name = "fred";
   ...
Name = "barney"; // whoops! we meant to reuse name

Ответ 3

Я понимаю необходимость в var, и он отлично подходит для нее. Отсутствие ключевого слова и просто определение переменных на лету без типа пугает. Ваш вред для следующего парня, который должен поддерживать ваш код или себя, если вам нужно переделать код, который вы не коснулись более года. Я не уверен, что это дверь, которая должна открываться в С#, и я надеюсь, что это не так, поскольку 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 object, что? Мне все еще нужно тратить время на поиски этого... нужен кошелёк intellisense, чтобы спасти день от ленивого программирования. Может включать тип возвращаемого значения в имя функции. Хорошая идея, теперь использование var ничего нам не спасло, заставив все мои функции иметь настоящие длинные имена.

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

Ответ 4

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

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

var myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;

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

myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;

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

Ответ 5

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

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

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

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

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

Ответ 6

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

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

bill=5;
bi11=bill+5

Какое значение счета?

Тем не менее, я нахожу, что иногда раздражает, чтобы напечатать:

DataOutputStream ds=new DataOutputStream();

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

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

Еще одна вещь: МОСТ того времени, когда код не должен быть похож на мой пример выше. Что вы должны делать, так это:

DataOutput ds=new DataOutputStream();

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

Ответ 7

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

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

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

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