Verlängerungsmethoden nicht für eine Schnittstelle
-
01-07-2019 - |
Frage
Inspiriert von der MVC das neueste Projekt Storefront ich arbeite verwendet Erweiterungsmethoden auf IQueryable Ergebnisse zu filtern.
Ich habe diese Schnittstelle;
IPrimaryKey
{
int ID { get; }
}
, und ich habe diese Erweiterung Methode
public static IPrimaryKey GetByID(this IQueryable<IPrimaryKey> source, int id)
{
return source(obj => obj.ID == id);
}
Lassen Sie uns sagen, ich habe eine Klasse, SimpleObj die IPrimaryKey implementiert. Wenn ich eine IQueryable von SimpleObj haben die GetByID Methode existiert nicht, es sei denn, ich explicitally als IQueryable von IPrimaryKey gegossen, die weniger als ideal ist.
Bin ich etwas fehlt hier?
Lösung
Es funktioniert, wenn es richtig gemacht. cfeduke-Lösung funktioniert. Allerdings müssen Sie nicht die IPrimaryKey
Schnittstelle generic, in der Tat machen, Sie müssen nicht Ihre ursprüngliche Definition ändern überhaupt:
public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey
{
return source(obj => obj.ID == id);
}
Andere Tipps
Edit: Konrad 's Lösung ist besser, weil seine viel einfacher. Die folgende Lösung funktioniert aber nur in Situationen ähnlich wie Object, wo eine Methode einer Klasse erforderlich ist, ohne dass die Vererbungshierarchie zu Fuß nach oben durch Reflektion abgerufen. Offensichtlich das wird hier nicht passiert.
Dies ist möglich, ich habe ein ähnliches Muster zu implementieren, als ich eine benutzerdefinierten Entity Framework-Lösung entwickelt, um mit Object arbeiten:
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; }
}
Snippet Verwendung:
var people = new List<Person>
{
new Person { Id = 1 },
new Person { Id = 2 },
new Person { Id = 3 }
};
var personOne = people.AsQueryable().GetById(1);
Das kann nicht aufgrund der Tatsache arbeiten, dass Generika haben nicht die Fähigkeit, Vererbungsmuster zu folgen. dh. IQueryable