Ответ 1
Необычно, похоже, что у VB есть специальная поддержка IEnumerable<T>
и неявно предоставляет индекс, который фактически вызывает Enumerable.ElementAtOrDefault
. ICollection<T>
extends IEnumerable<T>
, поэтому там существует одно и то же средство. ICollection<T>
не предоставляет "реального" индексатора, поэтому проблема при попытке использовать его с С#.
Пример программы:
Option Strict On
Public Class Test
Public Shared Sub Main(args As String())
Dim x as System.Collections.Generic.ICollection(Of String) = args
Console.WriteLine(x(0))
End Sub
End Class
Сгенерированный IL для Main:
.method public static void Main(string[] args) cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// Code size 15 (0xf)
.maxstack 2
.locals init
(class [mscorlib]System.Collections.Generic.IEnumerable`1<string> V_0)
IL_0000: ldarg.0
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: ldc.i4.0
IL_0004: call !!0
[System.Core]System.Linq.Enumerable::ElementAtOrDefault<string>(
class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
int32)
IL_0009: call void [mscorlib]System.Console::WriteLine(string)
IL_000e: ret
} // end of method Test::Main
Мне очень странно, что VB предоставляет это неявно - действительно опасно сделать так, чтобы он выглядел так, чтобы индексировать в коллекцию, которая не обязательно обеспечивает эффективную операцию индексирования.
Конечно, вы можете вызвать ElementAtOrDefault
самостоятельно, если вы довольны тем, что это делает.