Problem
If I have a class with a definition like this:
public class TestList : ObservableCollection<TestClass>, IList<ITestInterface>, ICollection<ITestInterface>, IEnumerable<ITestInterface>, IEnumerable
I cannot use the IEnumerable extension methods (System.Linq namespace) on objects of this class.
Things to Note
- The type in the
ObservableCollectionis different than the type in the collection interfaces, butTestClassdoes implementITestInterface - It is still possible to
foreachover the items in aTestListobject. Doing so gives the items the type ofTestClass - I do have a
usingstatement forSystem.Linqat the top of the file
It clearly has something to do with the fact that the type in the ObservableCollection is different than the other types in the class definition, but why? The collection can still be enumerated in a foreach statement, and that is basically what those extension methods do anyways (with additional logic of course).
Question
Why does creating a class that inherits from a collection of one type and implements collection interfaces of another type cause the extension methods in System.Linq to be unavailable to use on objects of the class?
Minimal, Complete, and Verifiable Example
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
var t = new TestList();
t.First(); //Extension method unavailable, compiler error
foreach (var item in t)
{
//item is of type TestClass
}
}
}
public interface ITestInterface { }
public class TestClass : ITestInterface { }
public class TestList : System.Collections.ObjectModel.ObservableCollection<TestClass>, IList<ITestInterface>, ICollection<ITestInterface>, IEnumerable<ITestInterface>, IEnumerable
{
//Method implementations are unnecessary for the example
ITestInterface IList<ITestInterface>.this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public bool IsReadOnly => throw new NotImplementedException();
public void Add(ITestInterface item) => throw new NotImplementedException();
public bool Contains(ITestInterface item) => throw new NotImplementedException();
public void CopyTo(ITestInterface[] array, int arrayIndex) => throw new NotImplementedException();
public int IndexOf(ITestInterface item) => throw new NotImplementedException();
public void Insert(int index, ITestInterface item) => throw new NotImplementedException();
public bool Remove(ITestInterface item) => throw new NotImplementedException();
IEnumerator<ITestInterface> IEnumerable<ITestInterface>.GetEnumerator() => throw new NotImplementedException();
}
}
Background
For those that are curious, I came across this while working with the Telerik RadGridView control (WPF). I was trying to use the .First() extension method on the Columns property of the grid, but the type of the Columns property has a class definition that is similar to what I provided above.