В неуниверсальном мире вы можете получить другое поведение при использовании var
вместо типа всякий раз, когда произойдет неявное преобразование, например, в цикле foreach
.
В приведенном ниже примере происходит неявное преобразование из object
в XmlNode
(неуниверсальный интерфейс IEnumerator
возвращает только object
).Если вы просто замените явное объявление переменной цикла на ключевое слово var
, это неявное преобразование больше не будет выполняться:
using System;
using System.Xml;
class Program
{
static void Foo(object o)
{
Console.WriteLine("object overload");
}
static void Foo(XmlNode node)
{
Console.WriteLine("XmlNode overload");
}
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root><child/></root>");
foreach (XmlNode node in doc.DocumentElement.ChildNodes)
{
Foo(node);
}
foreach (var node in doc.DocumentElement.ChildNodes)
{
// oops! node is now of type object!
Foo(node);
}
}
}
В результате этот код на самом деле выдает разные выходные данные в зависимости от того, использовали ли выvar
или явный тип.При var
будет выполнена перегрузка Foo(object)
, в противном случае будет перегрузка Foo(XmlNode)
.Выходные данные вышеприведенной программы, таким образом, таковы:
XmlNode overload
object overload
Обратите внимание, что это поведение полностью соответствует спецификации языка C #.Единственная проблема заключается в том, что var
выводит другой тип (object
) , чем вы ожидаете , и что этот вывод не очевиден при просмотре кода.
Я не добавилIL, чтобы держать это коротким.Но если вы хотите, вы можете взглянуть на ildasm и убедиться, что компилятор фактически генерирует разные инструкции IL для двух циклов foreach.