tags:

views:

175

answers:

3

Forgive me if this is a duplicate, but it's a minor issue for me and I can only spend so long on my curiosity. Why is it that when I use an implicitly typed loop variable in a foreach block, I get no Intellisense? The inferred type seems to be quite obvious.

I am using ReSharper, but when I switch the Intellisense to VS I get the same behaviour, and this don't think it's to blame.

EDIT: Sorry, a bit later, but I was iterating DataTable.Rows, which uses an untyped ieterator, as Marc explains below.

A: 

I've just checked in VS 2008, c# var variables in foreach has intellisense.

maybe the resharper is messing with you... is there a way to clean it's db or something like that?

Dani
+5  A: 

I suspect that the data you are enumerating is not typed - for example, a lot of things that were written in 1.1 only implement IEnumerable, and don't have a custom iterator (you don't actually need IEnumerable<T> to do typed iteration - and indeed you don't even need IEnumerable to use foreach; a lot of 1.1 typed wrote special enumerator types to avoid boxing/casting etc - lots of work). In many cases it would be a breaking change to fix them.

A trivial example here is PropertyDescriptorCollection:

var props = TypeDescriptor.GetProperties(obj);
foreach(PropertyDescriptor prop in props) {...} // fine

but actually, PropertDescriptorCollection's enumerator is just IEnumerator, so Current is object - and hence you'll always get object when you use var:

var props = TypeDescriptor.GetProperties(obj);
foreach(var prop in props) {...} // prop is "object"

Contrast this to the (equally 1.1) StringCollection; this has a custom enumerator (StringEnumerator); so if you used foreach with var, you'd get string (not object).

In anything 2.0 and above, it would be reasonable to expect better typing, for two reasons:

  • generics (for the simple cases), making it possible to write strongly-typed collections sensibly
  • iterator blocks (for the non-trivial cases), making it possible to write custom iterators without going insane

But even then there are still cases when you don't get the type you expect; you can either (and perhaps more clearly) specify the type manually, or use Cast<T>() / OfType<T>().

Marc Gravell
This happens to me a lot. Cast<T>() works, but I find it clearer to just not use var in this case.
Stuart Branham
@Stuart B - indeed; the "specify the type manually" involves less indirection too, so *marginally* quicker as well as clearer.
Marc Gravell
A: 

do you have the namespace of the class that you are using the var for ?

Yassir