2016-03-31 6 views
2

Я пытаюсь сделать функцию, которая в основном извлекает данные из моих коллекций MongoDB. Для этого я создал общий метод, который возвращает List<T>.Список кастингов <[KnownType]> в список <T> для соответствия функции типа возврата?

Моя проблема заключается в том, что я должен создать это List<T> для возврата, но я делаю это на основе typeofT. Я не уверен, что мне нужно сделать, чтобы угодить компилятор ..

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); 
    // ... 
} 

В обеих return линий я получаю ошибку вдоль линий «Не удается неявно преобразовать из List<[KnownType]> в List<T>. Который имеет смысл для меня , потому что typeofT не обязательно соответствовать typeof сказать BsonDocument. Но я сделал правильный чек, чтобы сделать это.

Могу ли я бросить List<[KnownType]> к List<T>?

+1

Имея, если утверждения для проверки типичного типа, похоже, преследуют цель использования дженериков в первую очередь. – juharr

+0

Если вы спросили меня, вы не должны изменять то, что вы возвращаете, в зависимости от типа, с которым он вызван. Это решение должно перейти от отдельного метода от вызываемого абонента через какой-либо обратный вызов. –

+0

Я пробовал это и его в основном ту же ошибку «Невозможно преобразовать тип» Список <[KnownType]> 'to' List '", просто пропуская слово неявное. – KDecker

ответ

1

Вы злоупотребляете общим синтаксисом. Общий код должен быть generic, т. Е. Работать с любым типом, который вы используете.

У вас должны быть разные методы, в зависимости от типа, который будет передан. Во что бы то ни стало, создайте действительно общие части в свой собственный общий метод, который могут вызвать ваши методы, специфичные для конкретного типа. Но у вызывающего, который уже знает, какой тип он использует, выберите соответствующий метод на основе этого типа, а затем просто используйте этот тип явно в каждом типе-специфическом методе.

Трудно сказать, что у вас есть пример, но если вы можете предоставить хороший Minimal, Complete, and Verifiable example, который четко показывает, что вы делаете, я был бы рад реорганизовать его, чтобы показать, что я имею в виду.

+0

Вы правы. Думаю, я злоупотребляю общим синтаксисом. Моя первоначальная мысль состояла в том, чтобы просто засунуть 7 больших функций, которые в основном делали то же самое в одной функции. // Возможно, если вместо 'T' я делаю тип интерфейсом, который определяет функцию преобразования. Хотя какой бы тип возвращался? 'InterfaceType.GetListType()'? ... // Или, я думаю, я могу просто вырезать вторую часть и вернуть ее вместо 7 функций и использовать общий 'Get..' – KDecker

1

Если вы уверены, что у вас есть List<KnownType>, который соответствует типу текущей конкретизации из List<T> вы можете привести его к требуемому родовому типу с помощью промежуточного литья в object:

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

Оставляя моральное суждение, следует ли вам это делать самому)

+0

О, вы грязные. – KDecker