In the non-generic world you might get different behavior when using var
instead of the type whenever an implicit conversion would occur, e.g. within a foreach
loop.
In the example below, an implicit conversion from object
to XmlNode
takes place (the non-generic IEnumerator
interface only returns object
). If you simply replace the explicit declaration of the loop variable with the var
keyword, this implicit conversion no longer takes place:
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);
}
}
}
The result is that this code actually produces different outputs depending on whether you used var
or an explicit type. With var
the Foo(object)
overload will be executed, otherwise the Foo(XmlNode)
overload will be. The output of the above program therefore is:
XmlNode overload
object overload
Note that this behavior is perfectly according to the C# language specification. The only problem is that var
infers a different type (object
) than you would expect and that this inference is not obvious from looking at the code.
I did not add the IL to keep it short. But if you want you can have a look with ildasm to see that the compiler actually generates different IL instructions for the two foreach loops.