#c# #var
#c# #var
Вопрос:
Я изучаю C # и .NET и часто использую ключевое слово var
в своем коде. Я позаимствовал идею у Эрика Липперта, и мне нравится, как это повышает удобство сопровождения моего кода.
Однако мне интересно… в блогах много написано о медленных ссылках, расположенных в куче, но я сам этого не наблюдаю. Это действительно медленно? Я имею в виду медленное время компиляции из-за вывода типа.
Комментарии:
1. Конечно, это не так. Он компилируется тем же способом, каким тип известен при компиляции
2. Повторите предложенный дубликат выше; Я не согласен — этот вопрос явно касается производительности среды ВЫПОЛНЕНИЯ (IL); этот вопрос конкретно касается производительности КОМПИЛЯТОРА. Эти два понятия совершенно не связаны.
Ответ №1:
Вы заявляете:
Я имею в виду медленное время компиляции из-за типа «вывод»
Это не замедляет работу компилятора. Компилятор уже должен знать тип результата выражения, чтобы проверить совместимость (прямую или косвенную) присваивания. В некотором смысле использование этого уже известного типа устраняет некоторые проблемы (например, потенциальную необходимость проверки на наследование, интерфейсы и операторы преобразования).
Это также не замедляет время выполнения; они полностью статичны, скомпилированы как обычные переменные c # (которыми они и являются).
Короче говоря… это не так.
Ответ №2:
‘var’ в C # — это не тот ВАРИАНТ, к которому вы привыкли в VB. var — это просто синтаксический сахар, который компилятор позволяет использовать для сокращения типа. Компилятор определяет тип правой части выражения и присваивает вашей переменной этот тип. Это вообще не влияет на производительность — точно так же, как если бы вы ввели выражение полного типа:
var x = new X();
точно так же, как
X x = new X();
Это кажется тривиальным примером, и это так. Это действительно замечательно, когда выражение намного сложнее или даже «невыразимо» (например, анонимные типы) и перечислимо.
Комментарии:
1. Недавно меня спросили «зачем вообще использовать var», и у меня был большой соблазн погрозить пальцем анонимным типам. Однако я считаю, что более практичным примером использования являются выражения LINQ, для поддержки которых он был вставлен, — где возвращаемый тип довольно сложно вручную вывести из запроса. Это может быть просто потому, что я объясняю программисту на C (новичку в c #), кого анонимные типы убили бы.
Ответ №3:
Во время компиляции Var заменяется вашим фактическим типом переменной. Вы думаете о dynamic
?
Ответ №4:
«Вариант» не имеет типа, поэтому доступ к состоянию (или преобразование внутреннего состояния) всегда должен проходить через два этапа: (1) Определение «реального» внутреннего типа и (2) Извлечение соответствующего состояния из этого «реального» внутреннего типа.
У вас нет этого двухэтапного процесса, когда вы начинаете с типизированного объекта.
Верно, «вариант», таким образом, имеет эти дополнительные накладные расходы. Подходящее использование в тех случаях, когда вам нужно удобство любого типа для простоты кода, как это делается с большинством языков сценариев или API очень высокого уровня. В таких случаях накладные расходы на «вариант» часто незначительны (поскольку вы все равно работаете с высокоуровневым API).
Однако, если вы говорите о « var
«, то это просто удобный способ для вас сказать: «Компилятор, поместите здесь правильный тип», потому что вы не хотите выполнять эту работу, и компилятор должен быть в состоянии разобраться с этим. В этом случае « var
» представляет собой не «вариант» (во время выполнения), а скорее простой синтаксис спецификации исходного кода.
Ответ №5:
Компилятор выводит тип из конструктора.
var myString = "123";
ничем не отличается от string myString = "123";
Кроме того, вообще говоря, ссылочные типы хранятся в куче, а типы значений — в стеке, независимо от того, объявлены ли они с использованием var .
Комментарии:
1. Было бы понятнее сказать «возвращаемый тип выражения», а не упоминать конструкторы, поскольку конструкторы — это всего лишь один крошечный вариант использования здесь
2. спасибо, это очень полезно, я не знал всех значений в стеке
3. @Marc — Ты прав. Спасибо за разъяснение. @Prashant — всегда пожалуйста. Я рад, что помог.
4. «Все типы значений хранятся в стеке» — это не фактическое утверждение. Смотрите (среди других мест): blogs.msdn.com/b/ericlippert/archive/2010/09/30 /…
5. Я бы даже не сказал здесь «вообще говоря». Не похоже, что наличие переменной экземпляра типа
int
в классе является необычным. Чрезмерные упрощения, подобные этому, на самом деле не помогают.