7

ユーザーが希望するタイプのリストを返すメソッドを作成しようとしています。これを行うために、私はジェネリックを使用していますが、これはあまりよく知らないので、この質問は明白かもしれません。問題は、このコードが機能せず、エラーメッセージがスローされることです。Cannot convert type Systems.Collections.Generic.List<CatalogueLibrary.Categories.Brand> to Systems.Collection.Generic.List<T>

private List<T> ConvertToList<T>(Category cat)
{            
     switch (cat)
     {
         case Category.Brands:
             return (List<T>)collection.Brands.ToList<Brand>();

     }
    ...
}

しかし、IList代わりに使用すると、エラーは発生しません。

private IList<T> ConvertToList<T>(Category cat)
{            
     switch (cat)
     {
         case Category.Brands:
             return (IList<T>)collection.Brands.ToList<Brand>();

     }
     ...
} 

この場合、IListを使用できるのにListを使用できないのはなぜですか?collection.Brandsはサードパーティのライブラリから型を返すBrandCollectionので、それがどのように作成されるのかわかりません。それBrandCollectionはIListから派生している可能性があり(推測しているだけです)、通常のリストには変換できませんが、IListに変換できますか?

4

1 に答える 1

9

には制約がないため、コンパイル時Tにのみ変換できます。object理論的には、を実装IList<object>および継承する新しいクラスが作成される可能性があるため、インターフェイスタイプへのキャストはコンパイラによってチェックされませんList<Brand>。ただし、との両方をList<T>継承するクラスは作成できないことがわかっているため、キャスト先は失敗します。しかし、あなたの場合、あなたはあなたのステートメントを通してタイプが何であるかを知っていて、キャストを強制したいと思っています。これを行うには、最初に次のようにキャストします。List<object>List<Brand>Tswitchobject

private List<T> ConvertToList<T>(Category cat)
{            
    switch (cat)
    {
        case Category.Brands:
            return (List<T>)(object)collection.Brands.ToList<Brand>();
    }
}

ただし、ここでのより大きな設計上の問題は、の既知の型の個別のリストがある場合、ジェネリックは最良の選択ではないということですT。ジェネリックスはT、何でもかまいませんが、基本型またはインターフェースに制限されている場合に適しています。ここでは、switchステートメントのブランチごとに個別のメソッドを作成する方がよいでしょう。

private List<Brand> ConvertToBrandList()
{
    return collection.Brands.ToList<Brand>();
}

これがないと、型安全性はほとんどありません。誰かがあなたのメソッドをで呼び出した場合はどうなりますConvertToList<int>(Category.Brands)か?

于 2013-03-24T20:35:22.320 に答える