开发者

Why is there no Intellisense with 'var' variables in 'foreach' statements in C#?

开发者 https://www.devze.com 2022-12-10 08:19 出处:网络
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

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>().

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号