Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclassing List<T> doesnt retain lists functionality

Tags:

c#

inheritance

I have created a subclass of a generic list so that I could implement a new interface

public class CustomersCollection : List<Customer>, IEnumerable<SqlDataRecord>
{
...
}

When I change the field definition to the new class (see example of old and new lines below) I get all sorts of compile errors on things that should exist in the original list.

public CustomersCollection Customers { get; set; } 
public void Sample()
{
    Console.WriteLine(Customers.Where(x=>x.condition).First().ToString());
}

Why does CustomersCollection does not inherit the IQueryable, IEnumerable interface implementations for List?

The official error is:

'CustomersCollection' does not contain a definition for 'Where' and no extension method 'Where' accepting a first argument of type 'CustomersCollection' could be found (are you missing a using directive or an assembly reference?)


It turns out that the custom implementation of IEnumerable causes all the extension methods that apply to IEnumerable to fail. Whats going on here?

like image 769
Matt Murrell Avatar asked Jun 24 '10 14:06

Matt Murrell


1 Answers

The extension methods are available to a class that inherits from List<T>. Perhaps you need to add using System.Linq; to your code file? Also check that you have a reference to System.Core.dll.

Edit

Since you have List<U> and IEnumerable<T> being inherited/implemented by the same class, you need to provide the type when you use the extension methods. Example:

CustomerCollection customers = new CustomerCollection();
customers.Add(new Customer() { Name = "Adam" });
customers.Add(new Customer() { Name = "Bonita" });
foreach (Customer c in customers.Where<Customer>(c => c.Name == "Adam"))
{
    Console.WriteLine(c.Name);
}

... based on

class Customer { public string Name { get; set; } }    

class Foo { }

class CustomerCollection : List<Customer>, IEnumerable<Foo>
{
    private IList<Foo> foos = new List<Foo>();

    public new IEnumerator<Foo> GetEnumerator()
    {
        return foos.GetEnumerator();
    }
}
like image 134
Anthony Pegram Avatar answered Oct 07 '22 16:10

Anthony Pegram