Extension methods do not work for the interface

Inspired by the MVC repository, the last project I'm working on uses extension methods for IQueryable to filter the results.

I have this interface;

IPrimaryKey { int ID { get; } } 

and I have this extension method

 public static IPrimaryKey GetByID(this IQueryable<IPrimaryKey> source, int id) { return source(obj => obj.ID == id); } 

Say I have a SimpleObj class that implements IPrimaryKey. When I have an IQueryable from SimpleObj, the GetByID method does not exist, unless I was explicitly included as an IQueryable from IPrimaryKey, which is less than ideal.

Did I miss something?

+6
c # extension-methods
source share
3 answers

This works when everything is done correctly. Cfeduke solution works. However, you do not need to create a common IPrimaryKey interface, in fact, you do not need to change the original definition at all:

 public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey { return source(obj => obj.ID == id); } 
+13
source share

Edit: Conrad is better because it is so much easier. The solution below works, but is only required in situations like ObjectDataSource, where the class method is retrieved through reflection without raising the inheritance hierarchy. Obviously this is not happening here.

This is possible, I had to implement a similar template when I developed a custom user solution for working with ObjectDataSource:

 public interface IPrimaryKey<T> where T : IPrimaryKey<T> { int Id { get; } } public static class IPrimaryKeyTExtension { public static IPrimaryKey<T> GetById<T>(this IQueryable<T> source, int id) where T : IPrimaryKey<T> { return source.Where(pk => pk.Id == id).SingleOrDefault(); } } public class Person : IPrimaryKey<Person> { public int Id { get; set; } } 

Fragment of use:

 var people = new List<Person> { new Person { Id = 1 }, new Person { Id = 2 }, new Person { Id = 3 } }; var personOne = people.AsQueryable().GetById(1); 
+4
source share

This cannot work due to the fact that generics are not able to follow inheritance patterns. i.e. IQueryable <SimpleObj> is not in the IQueryable <IPrimaryKey> inheritance tree

+2
source share

All Articles