1

重複の可能性:
foreach を使用せずにこのステートメントを再作成することは可能ですか?

基本クラスを共有する2つのクラスがあります

DealBookmarkWrapper : BookmarkWrapper
StoreBookmarkWrapper : BookmarkWrapper

また、次のような発言があります。

// 1 - This works
List<BookmarkWrapper> bm = new List<BookmarkWrapper>();
foreach(var d in deals)
{
    bm.Add(new DealBookmarkWrapper(d));
}

// 2 - This does not work
List<BookmarkWrapper> bm2 = deals.Select(d => new DealBookmarkWrapper(d)).ToList();

1) そのままで動作しますが、2 にはキャストが必要です。私が何か間違ったことをしているのか、それとも 2 番目のシナリオでキャストが本当に必要なのかはわかりません。

誰かがそれに光を当てますか?

4

4 に答える 4

7

あなたの問題は2つあります:

  • の型引数TToList<T>コンパイラによって として推論されるDealBookmarkWrapperため、List<DealBookmarkWrapper> が生成されます。
  • List<T>は共変型ではないため、 > から への表現を維持する変換は使用できませList<DealBookmarkWrapperList<BookmarkWrapper>。この理由の詳細については、この質問を参照してください。

Selectプロジェクションにキャストを追加することがこれを回避する方法であることはすでにわかっています。別の方法として、C# 4 + .NET 4.0 (またはそれ以降) では、型引数を明示的に指定し、次の共分散に依存しますIEnumerable<T>

deals.Select(d => new DealBookmarkWrapper(d))
     .ToList<BookmarkWrapper>()
于 2012-09-17T15:28:05.980 に答える
2
List<BookmarkWrapper> bm2 = deals.Select(d => new DealBookmarkWrapper(d)).Cast<BookmarkWrapper>().ToList(); 

または

List<BookmarkWrapper> bm2 = deals.Select(d => (BookmarkWrapper)(new DealBookmarkWrapper(d))).ToList(); 

あなたが持っているコードはList<DealBookmarkWrapper>、に変換できない を作成しList<BookmarkWrapper>ます。リストの型は、C# の型推論アルゴリズムによって決定されます。

上記の 2 つのオプションはどちらもDealBookmarkWrapperオブジェクトを作成しますが、参照を にキャストするBookmarkWrapperため、型推論はList<BookmarkWrapper>代わりに型を解決します。

于 2012-09-17T15:27:47.150 に答える
1

あなたは何も悪いことをしていません。は共変List<T>ではないため、オブジェクトを明示的にキャストする必要があります。詳細はこちら

于 2012-09-17T15:31:13.873 に答える
0

2 番目のシナリオでは、LINQ 式が派生オブジェクトのリスト ( List<DealBookmarkWrapper>) に投影されるため、キャストが必要です。ただし、基本オブジェクトのリストを作成する必要があります ( List<BookmarkWrapper>)。コンパイラにいくつかの型情報を「失わせる」ようにするため、それについて明示する必要があります。

最善の解決策は、呼び出しのCast<BookmarkWrapper>前にa を挿入して、これを明示的にし、読みやすい構文を維持することです。.ToList

var bm2 = deals.Select(d => new DealBookmarkWrapper(d))
               .Cast<BookmarkWrapper>()
               .ToList(); 
于 2012-09-17T15:26:12.190 に答える