Why is there no Intellisense with 'var' variables in 'foreach' statements in C#?
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 Intellisen开发者_如何学Pythonse? 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.
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>()
.
精彩评论