Задача
Если у меня есть класс с таким определением:
public class TestList : ObservableCollection<TestClass>, IList<ITestInterface>, ICollection<ITestInterface>, IEnumerable<ITestInterface>, IEnumerable
Я не могу использовать методы расширения IEnumerable
(пространство имен System.Linq
) для объектов этого класса.
Замечания
- Тип в
ObservableCollection
отличается от типа в интерфейсах коллекции, но TestClass
действительно реализует ITestInterface
- Все еще возможно
foreach
поверх предметов в TestList
объекте. Это дает элементам тип TestClass
- У меня есть
using
оператор для System.Linq
вверху файла
Это явно связано с тем, что тип в ObservableCollection
отличается от других типов в определении класса, но почему? Коллекция все еще может быть перечислена в операторе foreach
, и это в основном то, что эти методы расширения делают в любом случае (конечно, с дополнительной логикой).
Вопрос
Почему создание класса, который наследуется от коллекции одного типа и реализует интерфейсы коллекции другого типа, делает методы расширения в System.Linq
недоступными для использования на объектах класса?
Минимальный, полный и проверяемый пример
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();
}
}
Фон
Для тех, кому интересно, я сталкивался с этим, работая с элементом управления Telerik RadGridView (WPF). Я пытался использовать метод расширения .First()
для свойства Columns
сетки, но тип свойства Columns
имеет определение класса, аналогичное приведенному выше.