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?

War es hilfreich?

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 ist nicht in dem Vererbungsbaum von IQueryable

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top