Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extension Methods not working for an interface

Inspired by the MVC storefront the latest project I'm working on is using extension methods on IQueryable to filter 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);
}

Let's say I have a class, SimpleObj which implements IPrimaryKey. When I have an IQueryable of SimpleObj the GetByID method doesn't exist, unless I explicitally cast as an IQueryable of IPrimaryKey, which is less than ideal.

Am I missing something here?

like image 572
Kirschstein Avatar asked Sep 17 '08 12:09

Kirschstein


People also ask

Can we use extension method in interface?

You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself.

How do you override an extension method?

Extension methods cannot be overridden the way classes and instance methods are. They are overridden by a slight trick in how the compiler selects which extension method to use by using "closeness" of the method to the caller via namespaces.

Can you add extension methods to an existing static class?

No. Extension methods require an instance variable (value) for an object. You can however, write a static wrapper around the ConfigurationManager interface. If you implement the wrapper, you don't need an extension method since you can just add the method directly.

Do extension methods have to be static?

An extension method must be a static method. An extension method must be inside a static class -- the class can have any name. The parameter in an extension method should always have the "this" keyword preceding the type on which the method needs to be called.


1 Answers

It works, when done right. cfeduke's solution works. However, you don't have to make the IPrimaryKey interface generic, in fact, you don't have to change your original definition at all:

public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey
{
    return source(obj => obj.ID == id);
}
like image 182
Konrad Rudolph Avatar answered Sep 22 '22 06:09

Konrad Rudolph