Ранее я задал вопрос о том, почему я вижу, что во многих примерах используется var
ключевое слово, и получил ответ, что, хотя это необходимо только для анонимных типов, оно, тем не менее, используется для того, чтобы сделать написание кода «быстрее» / проще и «просто потому что».
По этой ссылке («C # 3.0 - Var Is Not Objec») я увидел, что он var
скомпилирован в правильный тип в IL (вы увидите его в середине статьи).
Мой вопрос заключается в том, насколько больше, если таковой имеется, IL-кода использует var
ключевое слово take, и будет ли оно даже близко к измеряемому уровню производительности кода, если бы он использовался повсеместно?
c#
performance
variables
var
Джефф Кеслинке
источник
источник
var
наиболее точно, работают с «Find All References» в Visual Studio 2019, поэтому, если он когда-либо был сломан, он был исправлен. Но я могу подтвердить, что он работает еще в Visual Studio 2012, поэтому я не уверен, почему вы утверждали, что он не работает.var
не будет считаться ссылкой,X
когда вы используете "Найти все ссылки" наX
. Интересно, что если вы используете «Найти все ссылки» наvar
в этом заявлении, он будет показывать вам ссылкиX
(хотя он все еще не перечислитvar
заявление). Кроме того, когда курсор включенvar
, он будет выделять все экземплярыX
в одном и том же документе (и наоборот).Ответы:
Для
var
ключевого слова нет дополнительного кода IL : полученный IL должен быть идентичным для неанонимных типов. Если компилятор не может создать этот IL, потому что он не может определить, какой тип вы намеревались использовать, вы получите ошибку компилятора.Единственная хитрость в том, что вы
var
получите точный тип, в котором вы, возможно, выбрали интерфейс или родительский тип, если вам нужно было установить тип вручную.Обновление 8 лет спустя
Мне нужно обновить это, так как мое понимание изменилось. Теперь я считаю, что это может
var
повлиять на производительность в ситуации, когда метод возвращает интерфейс, но вы бы использовали точный тип. Например, если у вас есть этот метод:Рассмотрим эти три строки кода для вызова метода:
Все три компилируются и выполняются, как и ожидалось. Однако первые две строки не совсем совпадают, а третья строка будет соответствовать второй, а не первой. Поскольку подпись
Foo()
должна возвращатьIList<int>
, именно так компилятор будет создаватьbar3
переменную.С точки зрения производительности, в основном вы не заметите. Однако существуют ситуации, когда производительность третьей строки может быть не такой быстрой, как производительность первой . Поскольку вы продолжаете использовать
bar3
переменную, компилятор может не иметь возможности отправлять вызовы методов одинаково.Обратите внимание, что возможно (вероятно, даже) джиттер сможет стереть эту разницу, но это не гарантировано. Как правило, вы все равно должны считаться
var
не фактором с точки зрения производительности. Это, конечно, совсем не похоже на использованиеdynamic
переменной. Но сказать, что это никогда ничего не меняет, может быть преувеличивать.источник
var i = 42;
(вывод типа int) НЕ идентиченlong i = 42;
. Так что в некоторых случаях вы можете делать неверные предположения о выводе типа. Это может вызвать неуловимые / крайние ошибки времени выполнения, если значение не подходит. По этой причине, все еще может быть хорошей идеей быть явным, если значение не имеет явного типа. Так, например,var x = new List<List<Dictionary<int, string>()>()>()
было бы приемлемо, ноvar x = 42
несколько двусмысленно и должно быть записано какint x = 42
. Но каждому свое ...var x = 42;
не однозначно. Целочисленные литералы имеют типint
. Если хочешь буквально долго пишиvar x = 42L;
.Foo
возвращается aList
, а не anIList
, тогда все три строки будут компилироваться, но третья строка будет вести себя как первая строка , а не вторая.Как говорит Джоэл, компилятор работает при компиляции , что должно быть тип вар, эффективно это просто трюк выполняет компилятор , чтобы сохранить нажатия клавиш, так, например ,
заменяется
компилятором до того, как будет сгенерирован любой IL. Сгенерированный IL будет точно таким же, как если бы вы набрали строку.
источник
Как никто еще не упомянул отражатель ...
Если вы компилируете следующий код C #:
Затем, используя отражатель, вы получите:
Таким образом, ответ явно не влияет на производительность во время выполнения!
источник
Для следующего метода:
Выход IL это:
источник
Компилятор C # определяет истинный тип
var
переменной во время компиляции. Там нет разницы в сгенерированном IL.источник
Итак, чтобы быть ясным, это ленивый стиль кодирования. Я предпочитаю нативные типы, учитывая выбор; Я возьму этот лишний «шум», чтобы убедиться, что я пишу и читаю именно то, что, как мне кажется, находится во время кода / отладки. * пожимает плечами *
источник
var
влияет ли это вообще на производительность; Вы просто высказываете свое мнение о том, должны ли люди его использовать.int
потому что она не может автоматически преобразоватьfloat
, но это точно то же самое, что произошло бы, если вы явно использовалиint
и затем изменили наfloat
. В любом случае, ваш ответ по-прежнему не отвечает на вопрос "var
влияет ли использование на производительность?" (особенно с точки зрения генерируемого IL)Я не думаю, что вы правильно поняли, что вы читаете. Если он компилируется к правильному типу, то нет никакой разницы. Когда я делаю это:
Компилятор знает, что это int, и генерирует код, как если бы я написал
Как говорится в сообщении, на которое вы ссылаетесь, скомпилировано в тот же тип. Это не проверка во время выполнения или что-то еще, требующее дополнительного кода. Компилятор просто выясняет, каким должен быть тип, и использует его.
источник
Нет никаких затрат производительности при использовании var. Тем не менее, я подозреваю, что производительность компиляции будет снижена, поскольку компилятор должен определить тип, хотя это, скорее всего, будет незначительным.
источник
Если компилятор может делать автоматическое определение типа, то с производительностью проблем не будет. Оба из них будут генерировать один и тот же код
однако, если вы создаете тип динамически (LINQ ...), тогда
var
это ваш единственный вопрос, и есть другой механизм, с которым можно сравнить, чтобы сказать, каков штраф.источник
Я всегда использую слово var в веб-статьях или руководствах.
Ширина текстового редактора онлайн-статьи невелика.
Если я напишу это:
Вы увидите, что приведенный выше текст предварительного кода слишком длинный и вытекает из поля, он скрыт. Читатель должен прокрутить вправо, чтобы увидеть полный синтаксис.
Вот почему я всегда использую ключевое слово var в записях веб-статей.
Весь представленный предварительный код просто помещается на экране.
На практике для объявления объекта я редко использую var, я полагаюсь на intellisense для более быстрого объявления объекта.
Пример:
Но для возврата объекта из метода я использую var, чтобы быстрее написать код.
Пример:
источник
«var» - это одна из тех вещей, которые люди либо любят, либо ненавидят (например, регионы). Хотя, в отличие от регионов, var абсолютно необходим при создании анонимных классов.
Для меня var имеет смысл, когда вы обновляете объект, например:
При этом, вы можете легко сделать:
Dictionary<string, string> dict =
new и intellisense заменит вам все остальное здесь.Если вы хотите работать только с определенным интерфейсом, вы не можете использовать var, если только метод, который вы вызываете, не возвращает интерфейс напрямую.
Resharper, кажется, на стороне использования «var» повсюду, что может подтолкнуть больше людей, чтобы сделать это таким образом. Но я согласен, что читать сложнее, если вы вызываете метод, и неясно, что возвращает имя.
Сам по себе var не тормозит, но есть одна оговорка, о которой не многие думают. Если вы это сделаете,
var result = SomeMethod();
то код после этого ожидает некоторого результата назад, где вы будете вызывать различные методы или свойства или что-то еще. Если выSomeMethod()
изменили свое определение на какой-то другой тип, но все равно выполнили контракт, которого ожидал другой код, вы просто создали действительно неприятную ошибку (если, конечно, нет модульных / интеграционных тестов).источник
Это зависит от ситуации, если вы попробуете использовать этот код ниже.
Выражение преобразуется в «ОБЪЕКТ» и сильно снижает производительность, но это отдельная проблема.
КОД:
Выше результатов с ILSPY.
Если вы хотите выполнить этот код, используйте приведенный ниже код и получите разницу во времени.
С уважением
источник