为什么我可以将索引器应用于VB.Net中的ICollection,但不能应用于C#中 [英] Why can I apply an indexer to an ICollection in VB.Net, but not in C#

查看:87
本文介绍了为什么我可以将索引器应用于VB.Net中的ICollection,但不能应用于C#中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我遇到此问题时,正在使用Ionic Zip库将某些代码从VB.Net转换为C#:

Was converting some code from VB.Net to C#, when I came across this, in some code using the Ionic Zip library:

Dim zipEntry1 As ZipEntry = zipFile1.Entries(0)

足够简单:

ZipEntry zipEntry1 = zipFile1.Entries[0];

我在C#上收到此错误:

I get this error on C#:

不能将带有[]的索引应用于类型的表达式 'System.Collections.Generic.ICollection'

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

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

Both are using the same version of the DLL, on both zipFile1.Entries is a generic ICollection.

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

I have tested the below on VB.Net, and it builds successfullly:

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];
        }
    }
}

为什么会这样,并且有办法解决吗?

Why does this happen, and is there a way around it?

推荐答案

Bizarly,似乎VB对IEnumerable<T>具有特殊支持,并且隐式提供了实际上调用

Bizarrely enough, it looks like VB has special support for IEnumerable<T> and implicitly provides an indexer which actually calls Enumerable.ElementAtOrDefault. ICollection<T> extends IEnumerable<T>, so the same facility exists there. ICollection<T> doesn't provide a "real" indexer, hence the problem when you try using it from 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:

Generated IL for 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隐式地提供了此功能-使它看起来很危险 ,因为它可以很好地索引到不一定提供集合的集合中高效的索引操作.

I find it very odd that VB provides this implicitly - it's really dangerous to make it look like it's fine to index into a collection which doesn't necessarily supply an efficient indexing operation.

当然,如果您对ElementAtOrDefault的操作感到满意,则可以自己打ElementAtOrDefault.

Of course, you can call ElementAtOrDefault yourself, if you're happy with what that does.

这篇关于为什么我可以将索引器应用于VB.Net中的ICollection,但不能应用于C#中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆