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
ObservableCollection
is different than the type in the collection interfaces, butTestClass
does implementITestInterface
- It is still possible to
foreach
over the items in aTestList
object. Doing so gives the items the type ofTestClass
- I do have a
using
statement forSystem.Linq
at 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.