2016-03-31 10 views
2

Ich versuche eine Funktion zu erstellen, die generisch Daten aus meinen MongoDB-Sammlungen abruft. Um dies zu tun, habe ich eine generische Methode konstruiert, die eine List<T> zurückgibt.Casting-Liste <[KnownType]> zu Liste <T>, um Rückgabetyp der Funktion zu entsprechen?

Mein Problem ist, dass ich diese List<T> erstellen muss, um zurückzukehren, aber ich mache es basierend auf der typeof . Ich bin nicht sicher, was ich tun muss, um den Compiler zu gefallen ..

public async Task<List<T>> GetDocsAsync<T>(
    CollectionTypes collection, // Enum representing my Collections 
    FilterDefinition<BsonDocument> search, 
    SortDefinition<BsonDocument> sort = null) 
{ 
    // Get BsonDocuments from the collection based on the search and sort criteria 
    List<BsonDocument> matchedDocs; 
    IMongoCollection<BsonDocument> MongoCollection = GetCollection(collection); 
    if (sort == null) matchedDocs = await MongoCollection.Find(search).ToListAsync(); 
    else matchedDocs = await MongoCollection.Find(search).Sort(sort).ToListAsync(); 

    // Return a List<T>, covert matchedDocs to List<T> if need be 
    Type docType = typeof(T); 
    if (docType == typeof(BsonDocument)) 
     return matchedDocs; 
    else if (docType == typeof(LogEvent_DBDoc)) 
     return LogEvent_DBDoc.ConvertFromBson(matchedDocs); 
    // ... 
} 

Bei beiden der return Linien erhalte ich einen Fehler nach dem Vorbild der „Kann nicht implizit List<[KnownType]>-List<T> konvertieren. Was macht Sinn für mich nicht, weil die typeofT nicht unbedingt entspricht die typeofBsonDocument sagen. Aber ich habe die richtige Prüfung vorgenommen, dies zu tun.

Kann ich werfen List<[KnownType]>-List<T>?

+1

Wenn Aussagen zu überprüfen, die generische Art scheint den Zweck der Verwendung von Generika in erster Linie zu besiegen. – juharr

+0

Wenn Sie mich gefragt haben, sollten Sie nicht ändern, was Sie zurückgeben, basierend auf dem Typ, mit dem es aufgerufen wird. Diese Entscheidung sollte durch einen Callback in eine vom Aufrufer getrennte Methode gehen. –

+0

Ich hatte versucht, und es ist im Grunde der gleiche Fehler "Kann nicht konvertieren Typ" Liste <[KnownType]> 'zu" Liste '", nur fehlt das Wort implizit. – KDecker

Antwort

1

Sie missbrauchen generische Syntax. Generischer Code sollte generisch sein, d.h. mit dem von Ihnen verwendeten Typ arbeiten.

Sie sollten verschiedene Methoden haben, abhängig vom Typ, der übergeben wird. Stellen Sie die wirklich generischen Teile auf jeden Fall in eine eigene generische Methode, die Ihre typspezifischen Methoden aufrufen können. Lassen Sie den Aufrufer, der bereits weiß, welchen Typ er verwendet, die entsprechende Methode basierend auf diesem Typ auswählen und dann diesen Typ in jeder typspezifischen Methode explizit verwenden.

Es ist schwer zu sagen, mit dem Beispiel, das Sie haben, aber wenn Sie eine gute Minimal, Complete, and Verifiable example bieten, die klar zeigt, was du tust, würde ich gerne umgestalten, um zu zeigen, was ich meine.

+0

Sie haben Recht .. Ich schätze, ich missbrauche die generische Syntax. Mein ursprünglicher Gedanke war, nur eine 7 große Funktionen zu schieben, die im Grunde genau dasselbe in eine Funktion tat. // Vielleicht, wenn ich anstelle von "T" den Typ eine Schnittstelle mache, die die Umwandlungsfunktion definiert. Was wäre der Rückgabetyp? 'InterfaceType.GetListType()'? ... // Oder ich schätze, ich kann einfach den zweiten Teil ausschneiden und ihn an Stelle der 7 Funktionen einfügen und den generischen 'Get..' verwenden. – KDecker

1

Wenn Sie sicher sind, dass Sie die List<KnownType> haben, die den Typ der aktuellen generischen Instanziierung List<T> entspricht, das Sie es auf den gewünschten generischen Typ mit Hilfe von Zwischen cast object abgeben können:

List<T> GetListOf<T>() { 
    if (typeof(T) == typeof(String)) { 
     var stringList = new List<String> { "a", "b" }; 
     return (List<T>)(object)stringList; 
    } 
    throw new NotSupportedException(); 
} 

Verlassen der moralisches Urteil, ob Sie dies zu sich selbst tun sollten)

+0

Oh du bist dreckig. – KDecker

Verwandte Themen