WARNING: This is a speculative post. Caveat emptor.
When we last left collection initializers, we were discussing default types for collection initializers. Since then we’ve thought further about the feature and are considering changing the design. The problem is that as nice as type inference is, as we started to dig into what that practically meant it started to become more and more difficult to figure out what a particular collection initializer might mean. Because the meaning of the initializer in the original design depends on the context, it’s meaning could change dramatically in different contexts. Of particular difficulty was figuring out just how a collection initializer would participate in generic method type inference (i.e. inferring the type arguments to a generic method)–an important topic given how much generic methods are used in LINQ.
Without going into too much detail, what we’re considering is significantly simplifying the design. Instead of inferring the meaning of a collection initializer from context, a standalone collection initializer will always infer an array type. So {1, 2, 3, 4} will always be a single dimensional array of Integer. If you want to initialize a collection type, you use an initializer similar to object member initializers (the initializer that uses “With”). For example:
Dim x = New List(Of Integer)() From { 1, 2, 3, 4 }
The use of the “From” keyword is provisional. It may be the right keyword, it might not, we’ll have to think further on that one. However, you get the idea. The downside of the new design is that it’s more typing in the situation where you were initializing a collection in a context like argument passing (although in the case of List, you could also say {1, 2, 3, 4}.ToList()) where you weren’t going to say the type at all. The upside is that it removes significant ambiguity–when you see “Foo({1, 2, 3, 4})” you know what you’re passing and in the case of generic methods, you aren’t going to get surprising results. This also makes the feature work more like the way C#’s anonymous arrays and collection initializers work, for those of you who care about that kind of thing.
Comments?