考虑以下代码:
var variables = System.Environment.GetEnvironmentVariables();
foreach (DictionaryEntry vari in variables)
{
Console.WriteLine(vari.Key);
Console.WriteLine(vari.Value);
}
它工作正常。由于
variables
是IDictionary
,因此它由DictionaryEntry
以及object Key
和object Value
组成。为什么我不能输入
foreach(var vari in variables)
?它给我error CS1061: 'object' does not contain a definition for 'Key/Value'...
似乎很奇怪,我找不到这种行为的原因。
DictionaryEntry
是struct
,但是我可以遍历List<DictionaryEntry>
很好。我当然知道IDictionary
不是通用的,但是manual说它包含DictionaryEntries
,因此应该可以使用var
... 最佳答案
可以,但是vari
隐式为object
类型。
您碰巧知道迭代器中的每个条目都是一个DictionaryEntry
,但编译器并非如此。据了解,IDictionary
的迭代元素类型只是object
。即使IDictionary.GetEnumerator
返回 IDictionaryEnumerator
,它仍然具有Current
属性,其类型为object
,而不是DictionaryEntry
。
令人讨厌的是,这本来可以做得更好。如果IDictionaryEnumerator
已使用IEnumerator.Current
的显式接口(interface)实现来实现,并提供了Current
类型的新DictionaryEntry
属性,则该方法将有效并且效率更高,因为它可以避免装箱。
C#规范的8.8.4节提供了C#编译器用来确定集合的元素类型的规则。
编辑:对于那些想看看如何可以声明IDictionaryEnumerator
的人,这是一个简短但完整的示例。请注意,这怎么不会在任何地方使用泛型,但是会在var
中使用Main
,但仍带有一个隐式键入为DictionaryEntry
的变量:
using System;
using System.Collections;
interface IJonDictionary : IEnumerable
{
new IJonDictionaryEnumerator GetEnumerator();
}
interface IJonDictionaryEnumerator : IEnumerator
{
new DictionaryEntry Current { get; }
}
class JonDictionary : IJonDictionary
{
private readonly IDictionary dictionary = new Hashtable();
public object this[object key]
{
get { return dictionary[key]; }
set { dictionary[key] = value; }
}
public void Add(object key, object value)
{
dictionary.Add(key, value);
}
public IJonDictionaryEnumerator GetEnumerator()
{
return new JonEnumerator(dictionary.GetEnumerator());
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private class JonEnumerator : IJonDictionaryEnumerator
{
private readonly IDictionaryEnumerator enumerator;
internal JonEnumerator(IDictionaryEnumerator enumerator)
{
this.enumerator = enumerator;
}
public DictionaryEntry Current
{
get { return enumerator.Entry; }
}
object IEnumerator.Current { get { return Current; } }
public bool MoveNext()
{
return enumerator.MoveNext();
}
public void Reset()
{
enumerator.Reset();
}
}
}
class Program
{
static void Main(string[] args)
{
var dictionary = new JonDictionary {
{ "x", "foo" },
{ "y", "bar" }
};
foreach (var entry in dictionary)
{
Console.WriteLine("{0} = {1}", entry.Key, entry.Value);
}
}
}
关于c# - 使用隐式DictionaryEntry遍历IDictionary,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19489682/