LINQ gets confused when implementing IEnumerable<T> twice

c#, collections, generics, ienumerable, linq

Solution

It's important to understand that the compiler has no concept of "primary" and "secondary" interface implementations when it comes to using an expression as an argument for a method call. Your type implements both `IEnumerable<IAssociation<...>>` and `IEnumerable<KeyValuePair<...>>` equally well, as far as conversions to those types are concerned. That's why the compiler needs more information.

The simplest approach (IMO) would be to introduce two new properties:

public IEnumerable<IAssociation<TKey, TValue>> Associations { get { return this; } }
public IEnumerable<KeyValuePair<TKey, TValue>> KeyValuePairs { get { return this; } }

That means you can really easily be specific:

var query = from x in table.Associations
            ...;

or

var query = from x in table.KeyValuePairs
            ...;

Not only does this help keep the compiler happy - it'll help anyone trying to read the code, too. If you find you use one of these much more than the other, you could always make `HashTable` only implement a single `IEumerable<>` and type and keep the other property.

Problem

My class implements `IEnumerable<T>` twice. How can I get LINQ to work without casting `hashtable` every time? I wrote my own covariant hashtable implementation that also inherits from .NET's `IDictionary<TKey, TValue>`. Ultimately, it implements `IEnumerable<T>` twice with different types for `T`. I implemented the primary enumerable interface implicitly, and the other one explicitly. Something like this (pseudocode): ``` 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(); } ``` When I `foreach` the hash table, it takes as expected the primary enumerable: ``` 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> } ``` Now I want it to do the same thing in LINQ, but it flings compiler errors at me because it does not know which interface to pick for the extension methods: ``` var xs1 = from x in hashtable // <-- 1 select x; var xs2 = hashtable.Select(x => x); // <-- 2 ``` Error 1: Could not find an implementation of the query pattern for source type 'HashTable'. 'Select' not found. Consider explicitly specifying the type of the range variable 'x'. Error 2: 'HashTable' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'HashTable' could be found (are you missing a using directive or an assembly reference?) Maybe there's some interface or inheritance trick I don't know about? For those who asked, here is the full tree of interfaces: ``` 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> ``` Now you can see why I couldn't make `KeyValuePair<TKey, TValue>` and `IAssociation<TKey, TValue>` the same.

Original source