c# - 为什么我可以将索引器应用于 VB.Net 中的 ICollection,但不能在 C# 中

标签 c# vb.net icollection

正在将一些代码从 VB.Net 转换为 C#,当我遇到这个时,在一些使用 Ionic Zip 库的代码中:

Dim zipEntry1 As ZipEntry = zipFile1.Entries(0)

足够简单:

ZipEntry zipEntry1 = zipFile1.Entries[0];

我在 C# 上遇到这个错误:

Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.ICollection'

两者都使用相同版本的 DLL,在 zipFile1.Entries 上都是通用的 ICollection

我已经在 VB.Net 上测试了以下内容,并且构建成功:

Option Strict On
Option Explicit On

Imports Ionic.Zip

Module Module1

    Sub Main()

        Dim zipFile1 = ZipFile.Read("C:\test")
        Dim zipEntry = zipFile1.Entries(0)

    End Sub

End Module

这不会构建:

using Ionic.Zip;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var zipFile1 = ZipFile.Read(@"C:\test");
            var zipEntry = zipFile1.Entries[0];
        }
    }
}

为什么会发生这种情况,是否有解决办法?

最佳答案

奇怪的是,看起来 VB 对 IEnumerable<T> 有特别的支持并隐含地提供一个索引器,它实际上调用 Enumerable.ElementAtOrDefault . ICollection<T>延伸IEnumerable<T> ,因此那里存在相同的设施。 ICollection<T>不提供“真正的”索引器,因此当您尝试从 C# 使用它时会出现问题。

示例程序:

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

为 Main 生成的 IL:

.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你自己,如果你对这样做感到满意的话。

关于c# - 为什么我可以将索引器应用于 VB.Net 中的 ICollection,但不能在 C# 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15864783/

相关文章:

c# - 使用 asp.net 和 C# 集成 Paypal

c# - 筛选对象列表,其中嵌套集合与数组匹配

.net - Environment.MachineName 是否有可能返回零长度字符串

asp.net - 如何通过弹出框要求用户确认操作?

vb.net 检测Web浏览器控件中的链接是否被单击

c# - 将 IEnumerable<Tuple<Parent, Child>> 转换为 IEnumerable<Parent>

c# - 将 ICollection 序列化为 JSON

c# - 日期的计算算法

c# - 找不到路径 '/apple-touch-icon-120x120-precomposed.png' 的 Controller

c# - 如何在组合框中显示 2 列? (多个值)