2011-08-05 43 views
0

我試圖在多個ISet上使用Concat()來創建一個更大的ISet。所以,我想下面的代碼:使用Aggregate連接ISet

public class Foo 
{ 
    private Dictionary<Bii, ISet<Faa>> items = new Dictionary<Bii, ISet<Faa>>(); 

    public ISet<Faa> GetCompleteList() 
    { 
     ISet<Faa> result = items.Values.Aggregate((x,y) => x.Concat(y)); 
     return result; 
    } 
} 

的問題是,這將導致一個編譯器錯誤:

Cannot implicitly convert type System.Collections.Generic.IEnumerable<Faa> to System.Collections.Generic.ISet<Faa> . An explicit conversion exists (are you missing a cast?)

而第二個錯誤:

Cannot convert lambda expression to delegate type System.Func<System.Collections.Generic.ISet<Faa>,System.Collections.Generic.ISet<Faa>,System.Collections.Generic.ISet<Faa>> because some of the return types in the block are not implicitly convertible to the delegate return type

我也嘗試使用演員陣容:

ISet<Faa> result = items.Values.Aggregate((x,y) => (ISet<Faa>)x.Concat(y)); 

但是這會給我一個InvalidCastException,因爲它應該是ConcatIterator或某種。

我該如何做好演員才能將所有ISets加入一個ISet?

回答

2

LINQ功能,如Concat返回IEnumerable。此次通話結束後,不再有ISet。你可以重建一個,但:

ISet<Faa> result = new HashSet<Faa>(items.Values.Aggregate((x,y) => x.Concat(y))); 

或者,使用SelectMany簡化:

ISet<Faa> result = new HashSet<Faa>(items.Values.SelectMany(value => value)); 
1

你可以嘗試這樣的事:

ISet<Faa> result = items.Values.Aggregate(new HashSet<Faa>(), 
              (a, x) => { a.UnionWith(x)); return a; }); 
+0

雖然[朱利安的第二個建議使用'SelectMany'](首選項)(http://stackoverflow.com/questions/6955373/concatenate-an-iset-using-aggregate/6955450#6955450)是可取的,imo。 – LukeH

+0

你能告訴我爲什麼嗎?速度更快嗎? – Marnix

+0

@Marnix:我認爲'SelectMany'版本更簡單,更具可讀性。我期望的表現幾乎完全一樣(''HashSet ''構造函數可能使用'UnionWith'或者相當於幕後的東西)。儘管如此,你必須要做基準測試。 – LukeH

0

如果你不想改變任何傳入套,你可以做這樣的事情:

public ISet<Faa> GetCompleteList() 
{ 
    ISet<Faa> result = new HashSet<Faa>(items.Values.SelectMany(x => x)); 
    return result; 
} 

如果你不想引入一個具體的類型,你可以追加到第一個傳入的集合,但是你會改變那個不如恆星。