为什么我可以,即使它没有实现IList(重点)指数访问KeyCollection / ValueCollection一个项目? [英] Why can I access an item in KeyCollection/ValueCollection by index even if it doesn't implement IList(Of Key)?
问题描述
我注意到一个奇怪的VB.NET的事情。从<一个未来href=\"http://stackoverflow.com/questions/36918321/first-item-in-a-sorteddictionary/36918491?noredirect=1#comment61401046_36918491\">this问题我提供了一种方法通过索引来访问字典的密钥和值 KeysCollection
和 ValuesCollection
得到的,也就是说,第一个项目。我知道,这让只感觉在 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
andValuesCollection
via index to get, say, the first item. I know that it makes only sense in aSortedDictionary
since a normalDictionary
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 theValueCollection
. Both implementICollection<T>
which is the parent interface ofIList<T>
. So you can loop it and it has aCount
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屋!