2016-03-31 9 views
2

MongoDBコレクションから一般的にデータを取得する関数を作成しようとしています。これを行うために、List<T>を返すジェネリックメソッドを構築しました。リストを<[KnownType]>にキャストすると、関数の戻り値の型に一致するリスト<T>になりますか?

私の問題は、返すためにはList<T>を作成する必要がありますが、typeofTに基づいています。私は..私は「暗黙のうちにList<[KnownType]>からList<T>に変換できませんの線に沿ってエラーを受け取るreturnラインの両方で

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

私はコンパイラを喜ばせるために何をする必要があるかわからない。私には理にかなって、typeofTは必ずしも一致しないため、typeofBsonDocument言う。しかし、私はこれを行うには、適切なチェックを行っている。

私はList<T>List<[KnownType]>をキャストすることはできますか?

+1

ジェネリック型をチェックするためのif文を持つことは、最初にジェネリック型を使う目的を打ち負かしているようです。 – juharr

+0

あなたが私に尋ねられたなら、それが呼び出されたタイプに基づいてあなたが返すものを変更すべきではありません。その決定は、何らかのコールバックによって、呼び出し先とは別の方法に移行する必要があります。 –

+0

私はこれを試していましたが、基本的には同じエラーです。 "リスト<[KnownType]>'を 'List 'に変換できません。 – KDecker

答えて

1

一般的な構文を悪用しています。汎用コードとする必要があります。つまり、使用するタイプを問わず使用できます。

渡すタイプに応じて、異なるメソッドを用意する必要があります。是非、実際のジェネリックパーツを型固有のメソッドで呼び出せる独自のジェネリックメソッドにしてください。しかし、使用している型をすでに知っている呼び出し側に、その型に基づいて適切なメソッドを選択し、各型固有のメソッドでその型を明示的に使用するようにしてください。

あなたが持っている例で言うのは難しいですが、あなたが行っていることを明確に示す良いMinimal, Complete, and Verifiable exampleを提供できる場合は、私が何を意味するのかをリファクタリングすることができます。

+0

あなたは正しいです。私は一般的な構文を乱用していると思います。私の最初の考えは、基本的にまったく同じことを1つの機能に加えた7つの大きな機能を押し出すことでした。 // 'T'の代わりに型を変換関数を定義するインタフェースにしているのかもしれません。戻り値の型は何ですか? 'InterfaceType.GetListType()'?... //または、私はちょうど2番目の部分を切り取り、7つの関数の代わりに戻して、一般的な 'Get ..'を使うことができると思います。 – KDecker

1

、あなたがobjectに、中間のキャストの助けを借りて、必要なジェネリック型にキャストすることができますList<T>の現在の一般的なインスタンス化のタイプと一致するList<KnownType>を持っていることを確認している場合:

残し
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

関連する問題