我的班级实施IEnumerable<T>
了两次。我怎样才能让 LINQ 工作而无需hashtable
每次都进行强制转换?
我编写了自己的协变哈希表实现,它也继承自 .NET 的IDictionary<TKey, TValue>
. 最终,它IEnumerable<T>
使用不同类型的T
. 我隐式地实现了主要的可枚举接口,而另一个显式地实现了。像这样的东西(伪代码):
class HashTable<TKey, TValue> :
...
IEnumerable<out IAssociation<out TKey, out TValue>>,
IEnumerable<out KeyValuePair<TKey, TValue>>
{
// Primary:
public IEnumerator<IAssociation<TKey, TValue>> GetEnumerator();
// Secondary:
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator();
}
当我foreach
使用哈希表时,它按预期采用了主要的可枚举:
using System;
using System.Collections.Generic;
using System.Linq;
var hashtable = new HashTable<string, int>();
foreach (var kv in hashtable)
{
// kv is IAssociation<string, int>
}
现在我希望它在 LINQ 中做同样的事情,但它会向我抛出编译器错误,因为它不知道为扩展方法选择哪个接口:
var xs1 = from x in hashtable // <-- 1
select x;
var xs2 = hashtable.Select(x => x); // <-- 2
错误 1:找不到源类型“HashTable”的查询模式的实现。未找到“选择”。考虑明确指定范围变量“x”的类型。
错误 2:“HashTable”不包含“Select”的定义,并且找不到接受“HashTable”类型的第一个参数的扩展方法“Select”(您是否缺少 using 指令或程序集引用?)
也许有一些我不知道的接口或继承技巧?
对于那些询问的人,这里是完整的接口树:
using SCG = System.Collections.Generic;
public class HashTable<TKey, TValue>
: IKeyedCollection<TKey, TValue>, SCG.IDictionary<TKey, TValue>
public interface IKeyedCollection<out TKey, out TValue>
: ICollection<IAssociation<TKey, TValue>>
public interface ICollection<out T> : SCG.IEnumerable<T>
public interface IAssociation<out TKey, out TValue>
// .NET Framework:
public interface IDictionary<TKey, TValue>
: ICollection<KeyValuePair<TKey, TValue>>
public interface ICollection<T>
: IEnumerable<T>
现在你可以明白为什么我做不到KeyValuePair<TKey, TValue>
了IAssociation<TKey, TValue>
。