为什么我可以,即使它没有实现IList(重点)指数访问KeyCollection / ValueCollection一个项目? [英] Why can I access an item in KeyCollection/ValueCollection by index even if it doesn't implement IList(Of Key)?

查看:523
本文介绍了为什么我可以,即使它没有实现IList(重点)指数访问KeyCollection / ValueCollection一个项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到一个奇怪的VB.NET的事情。从<一个未来href=\"http://stackoverflow.com/questions/36918321/first-item-in-a-sorteddictionary/36918491?noredirect=1#comment61401046_36918491\">this问题我提供了一种方法通过索引来访问字典的密钥和值 KeysCollection Values​​Collection 得到的,也就是说,第一个项目。我知道,这让只感觉在 SortedDictionary ,因为一个正常的词典不下令(当然,你不应该依赖其顺序)。

下面是一个简单的例子:

 昏暗sortedDict作为新SortedDictionary(中日期时间,字符串)
sortedDict.Add(DateTime.Now,富)昏暗的按键作为SortedDictionary(中日期时间,字符串).KeyCollection = sortedDict.Keys
昏暗的值作为SortedDictionary(中日期时间,字符串).ValueCollection = sortedDict.Values
昏暗firstkey为DATETIME =键(0)
昏暗firstValue作为字符串值=(0)

但我感到惊讶的是这个问题的提问者说,它不能编译,而它编译和作品对我来说没有问题:

  System.Diagnostics.Debug.WriteLine(键:{0}值:{1},firstkey,firstValue)键:2016年4月29日10时15分23秒价值:富

那么,为什么我可以用它像有一个索引,如果没有真正之一<一个href=\"https://msdn.microsoft.com/en-us/library/ms132259(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#$c$c-snippet-1\"相对=nofollow> SortedDictionary(中TKEY的,TValue).KeyCollection 级并没有同时在的 ValueCollection 。这两个实施的ICollection&LT; T&GT; 的父接口的IList&LT; T&GT; 。所以,你可以循环它,它有一个计数属性,但正如我上面你无法通过索引来访问项目。

请注意,它是没有扩展名的内部新鲜的控制台应用程序。我不能去索引的定义是(也没有用了ReSharper)。为什么它为我工作?

边注:它不会在C#中工作。我得到预期的编译器错误:


  

无法适用与[]索引到类型的前pression
  SortedDictionary.KeyCollection


  VAR字典=新SortedDictionary&LT;日期时间,字符串&GT;();
dict.Add(DateTime.Now,富);
DateTime的DT = dict.Keys [0]; // 这里

下面是编译VB.NET code的截图:

在这里输入的形象描述


解决方案

它调用 Enumerable.ElementAtOrDefault ,而不是索引。

  // [一十月13日至10月31日]
IL_001f:// ldloc.1钥匙
IL_0020:ldc.i4.0
IL_0021:致电!! 0 / *值类型[mscorlib程序] System.DateTime的* / [System.Core程序] System.Linq.Enumerable :: ElementAtOrDefault&LT; VALUETYPE [mscorlib程序] System.DateTime的&GT;(类[mscorlib程序] System.Collections.Generic。 IEnumerable`1&LT;!0 / *值类型[mscorlib程序] System.DateTime的* /&gt;中INT32)
IL_0026:// stloc.2 firstKey

此行​​为被记录在href=\"https://msdn.microsoft.com/en-us/library/ms234437.aspx\" rel=\"nofollow\"> Visual Basic语言规范的


  

T ,不已经有一个默认的属性被认为具有以下一般形式的默认属性每一个可查询集合类型的元素类型是:


  
  

公共只读默认属性项目(指数为整数)作为T形
    得到
        返回Me.ElementAtOrDefault(指数)
    到底得的
高端物业


  
  

默认属性只能被称为使用默认的属性访问语法;默认属性不能用名称引用。例如:


  
  

昏暗客户为IEnumerable(的顾客)= ...
昏暗的customerThree =客户(2)错误,没有这样的属性
昏暗customerFour = customers.Item(4)

如果集合类型不具有 ElementAtOrDefault 成员,会发生编译时错误。


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 ValuesCollection via index to get, say, the first item. I know that it makes only sense in a SortedDictionary since a normal Dictionary is not ordered (well, you should not rely on its order).

Here's a simple example:

Dim sortedDict As New SortedDictionary(Of DateTime, String)
sortedDict.Add(DateTime.Now, "Foo")

Dim keys As SortedDictionary(Of DateTime, String).KeyCollection = sortedDict.Keys
Dim values As SortedDictionary(Of DateTime, String).ValueCollection = sortedDict.Values
Dim firstkey As DateTime = keys(0)
Dim firstValue As String = values(0)

But I was surprised that the question's asker said that it doesn't compile whereas it compiles and works for me without a problem:

System.Diagnostics.Debug.WriteLine("Key:{0} Value:{1}", firstkey, firstValue) ' Key:04/29/2016 10:15:23 Value:Foo

So why can I use it like there was an indexer if there isn't actually one in SortedDictionary(Of TKey, TValue).KeyCollection-class and also none in the ValueCollection. Both implement ICollection<T> which is the parent interface of IList<T>. So you can loop it and it has a Count property, but you can't access items via index as I do above.

Note that it's a fresh console application with no extensions inside. I can't go to the definition of the indexer either(also not with resharper). Why does it work for me?

Side-note: it doesn't work in C#. I get the expected compiler error:

Cannot apply indexing with [] to an expression of type 'SortedDictionary.KeyCollection'

var dict = new SortedDictionary<DateTime, string>();
dict.Add(DateTime.Now, "Foo");
DateTime dt = dict.Keys[0]; // here

Here's a screenshot of the compiling VB.NET code:

解决方案

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.

这篇关于为什么我可以,即使它没有实现IList(重点)指数访问KeyCollection / ValueCollection一个项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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