Список приведения<<KnownType]> к списку<T> соответствует типу возвращаемого значения функции?

Я пытаюсь создать функцию, которая в общем случае получает данные из моих коллекций MongoDB. Для этого я создал общий метод, который возвращает List<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> ?

2 ответа

Решение

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

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

Трудно сказать с примером, который у вас есть, но если вы можете предоставить хороший Минимальный, Полный и Проверяемый пример, который ясно показывает, что вы делаете, я был бы рад его рефакторинг, чтобы показать, что я имею в виду.

Если вы уверены, что у вас есть 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();
}

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

Другие вопросы по тегам