c#linq func式内のienumerableに関するc#ハッシュセットユニオンは機能しません(precompilerバグの可能性)

StackOverflow https://stackoverflow.com/questions/3935557

質問

Microsoft .NETフレームワーク4.0を使用しています。

私はaの集合体を使用してこれに遭遇しました Dictionary<T, List<T>> タイプのセットを抽出します T すべてのタイプで使用される値 List<T> 辞書のリスト。これが私が同じ動作を示すことを考え出すことができる最も簡単なケースです。

まず、 ドキュメンテーション 州、以下 します 仕事:

var set = new HashSet<int>();
var list = new LinkedList<int>();
var newSet = set.Union(list);

つまり、電話することができます Union aで HashSet とともに List 議論として(それは実装されているので IEnumerable).

一方、a内の同等の式 Func linqの議論 Aggregate 式はエラーを生成します(少なくともプレキサラー):

new List<int>[] { new List<int>() }.Aggregate(new HashSet<int>(), (acc, list) => acc.Union(list));

それは、ユニオンの議論がハッシュセットであると予想しており、Linq/FUNC式以外の行動に反して、それが与えられた場合に協力します。

問題に出会ったときに使用していた現実世界の例は、次のとおりです。

public AdjacencyListGraph(Dictionary<TVertex, LinkedList<TVertex>> adjacencyList)
{
    var vertices = adjacencyList.Aggregate(new HashSet<TVertex>(),
    (vertices, list) => vertices.Union(list.Value));
}

変換できないと不平を言っています IEnumerable<TVertex>HashSet<TVertex>...

役に立ちましたか?

解決

問題は、実際には、アキュムレータタイプのハッシュセットをIENUMERABLEで置き換えようとすることにあります。ユニオンメソッドはハッシュセットにアイテムを追加しませんが、結果の結合で新しいIENUMERABLEを返します。

コードを次のように変更する必要があります。

    // select from keys
    var vertices = new HashSet<TVertex>(adjacencyList.Keys);

また

    // select from values
    var vertices = new HashSet<TVertex>(adjacencyList.SelectMany(dictEntry => dictEntry.Value));

他のヒント

ここでの問題は、あなたの理解にあります Select 方法。渡されたラムダは、リストを受け取るのではなく、リストの要素を受け取ります。したがって、あなたが名前を付けた変数 list 実際にはタイプです int 互換性がありません Union.

これがあなたがやろうとしていることのより明確な例です

new List<int>().Select( (int list) => new HashSet<int>().Union(list));

タイプの推論が削除されたため、これが機能しない理由ははるかに明確です。

new List<int>().Select(list => new HashSet<int>().Union(list));

あなたが使用することを期待すると思います SelectMany ここで、結果がそうであることを望まない限り IEnumerable<IEnumerable<T>>.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top