- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
考虑这段代码:
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
...
最佳答案
Why cannot I type foreach(var vari in variables)?
好吧,你可以 - 但 vari
隐式属于 object
类型。
您碰巧知道迭代器中的每个条目都是一个 DictionaryEntry
,但编译器不知道。据它所知,IDictionary
的迭代元素类型只是object
。尽管 IDictionary.GetEnumerator
返回 IDictionaryEnumerator
,它仍然有一个 Current
属性,其类型为 object
,而不是 DictionaryEntry
。
令人讨厌的是,这本可以做得更好。如果 IDictionaryEnumerator
已使用 IEnumerator.Current
的显式接口(interface)实现来实现,并提供了 DictionaryEntry
类型的新 Current
属性>,那么这将有效并且因为它可以避免装箱而更有效。
C# 规范的第 8.8.4 节提供了 C# 编译器用于确定集合元素类型的规则。
编辑:对于那些想了解如何声明 IDictionaryEnumerator
的人,这里有一个简短但完整的示例。请注意,这并没有在任何地方使用泛型,但是确实在 Main
中使用了 var
,仍然有一个隐式类型为 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/
我是一名优秀的程序员,十分优秀!