正在将一些代码从 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/