If one loops through an XmlNodeList like this
foreach (XmlNode foo in xmlNodeList) {string baa = foo.Attributes["baa"].Value;}
everything works as expected - foo is clearly of type XmlNode and the VS.NET IDE shows methods and fields.
On the other hand
foreach (var foo in xmlNodeList) { string baa = foo.Attributes["baa"].Value; }
is not compiling because here foo is of type object. Type inference sort of works but infers object.
Apparently, the elements of XmlNodeList are not of one defined type, but assigning them to XmlNode instead of var does something implicitly (casting or unboxing).
First question: what's the mechanism behind that?
Second (related) question: how to find the types one can use in this kind of loop? Does the VS.NET IDE help?
XmlNodeList
implements only the non-generic IEnumerable
interface, and not something like IEnumerable<XmlNode>
with generics. This prevents strong typing of its elements until you cast appropriately, so the compiler has no choice but to map the implicit type declaration to object
in your foreach.
If you insist on using the var
keyword, you can cast the elements of xmlNodeList
like so:
foreach (var foo in xmlNodeList.Cast<XmlNode>())
{
string baa = foo.Attributes["baa"].Value;
}
But that's ugly, and requires more keystrokes anyway. You may as well just explicitly declare XmlNode foo
, and let the foreach cast it for you on the fly.
As BoltClock notes, XmlNodeList
only implements IEnumerable
.
The foreach
loop automatically does casting for you behind the scenes, so this:
List<object> values = new List<object> { "x", "y", "z" };
foreach (string x in values)
{
...
}
is entirely legal, and performs a cast (which can throw an exception, of course) on each value.
It's not really clear to me what you mean by your second question - but I'd just recommend that you explicitly use XmlNode
in your loop. If you really want to use var
, you could write:
foreach (var foo in xmlNodeList.Cast<XmlNode>())
but that feels like overkill to me...
XmlNodeList has been in the .NET Framework before it supported generics. Because of that, it implements only the non-generic interface IEnumerable
and not the generic IEnumerable<T>
.
To know which types can be in this list you need to read the documentation. The best way is the indexer.
BTW: The IDE hasn't been called VS.NET since Visual Studio 2005 was released :-) It is called VS only since then.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With