I\'ve noticed a strange VB.NET thing. Coming from this question I\'ve provided a way to access keys and values of dictionaries\' KeysCollection
and Values
It invokes Enumerable.ElementAtOrDefault
, not the indexer.
// [10 13 - 10 31]
IL_001f: ldloc.1 // keys
IL_0020: ldc.i4.0
IL_0021: call !!0/*valuetype [mscorlib]System.DateTime*/ [System.Core]System.Linq.Enumerable::ElementAtOrDefault<valuetype [mscorlib]System.DateTime>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0/*valuetype [mscorlib]System.DateTime*/>, int32)
IL_0026: stloc.2 // firstKey
This behavior is documented in the Visual Basic Language Specification, 11.21.3:
Every queryable collection type whose element type is
T
and does not already have a default property is considered to have a default property of the following general form:Public ReadOnly Default Property Item(index As Integer) As T Get Return Me.ElementAtOrDefault(index) End Get End Property
The default property can only be referred to using the default property access syntax; the default property cannot be referred to by name. For example:
Dim customers As IEnumerable(Of Customer) = ... Dim customerThree = customers(2) ' Error, no such property Dim customerFour = customers.Item(4)
If the collection type does not have an
ElementAtOrDefault
member, a compile-time error will occur.
There is a considerable performance cost when we use Enumerable.ElementAtOrDefault or Enumerable.ElementAt. Unless the source implements IList(of T) interface, Linq does not have shorter route to get to the element at the specified index. So it iterates each element untill iteration count reaches to value of specified index. No magic. Enumerable. Count() has the same story except in this case ICollection interface if implemented by source, Linq grabs it otherwise iteration untill the last element is required to produce Count. I don't know why Vb.net allowing it implicitly because chances are that cases like this will remain unnoticed until I face serious performance issue. Dictionary only implements ICollection not IList. I think one needs to be careful with Vb.net as it is not as strictly typed language as C#.