为什么我不能输入 foreach(var vari in variables)?
好吧,您可以-但vari
隐含地属于 type object
。
您碰巧知道迭代器中的每个条目都是 a DictionaryEntry
,但编译器不知道。据它所知,它的迭代元素类型IDictionary
只是object
. 即使IDictionary.GetEnumerator
返回一个IDictionaryEnumerator
,它仍然有Current
一个类型为object
,而不是的属性DictionaryEntry
。
令人讨厌的是,这本来可以做得更好。如果IDictionaryEnumerator
已使用 的显式接口实现来实现IEnumerator.Current
,并提供了Current
type 的新属性DictionaryEntry
,那么这将有效并且更有效,因为它可以避免装箱。
C# 规范的第 8.8.4 节提供了 C# 编译器用来确定集合元素类型的规则。
编辑:对于那些想看看如何IDictionaryEnumerator
声明的人,这里有一个简短但完整的例子。请注意,这不会在任何地方使用泛型,而是使用in 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);
}
}
}