2017-05-16 59 views
1

出於好奇,我想在linq流中添加一個元素給一個可枚舉元素,而不退出流或將單個元素轉換爲數組。追加單個項目以linq語句列出

因此,而不是這樣的:

myEntity.SelectMany(e => e.SubEntities.Concat(new []{e})).yadayadayada 

我希望有一個不同的命令,其中我將不需要的單個元件換到一個數組:

myEntity.SelectMany(e => e.SubEntities.SomeBuiltInFunc(e)).yadayadayada 

myEntity.SelectMany(e => e.SubEntities.ToList().SomeBuiltInFunc(e)).yadayadayada 

myEntity.SelectMany(e => SomeBuiltInFunc(e.SubEntities, e).yadayadayada 

目前我錯過的語言中的任何構造都可以做到這一點,而無需創建新的自定義函數或擴展方法。

+0

這不是真的強大到足以成爲一個答案,但你可以使用'Enumerable.Repeat (e,1)'在技術上避免構造一個數組。 – recursive

+2

您需要編寫自己的擴展方法來完成該操作。 'Enumerable.Repeat'不太可讀,你也需要'Concat'。無論如何,擴展方法有什麼問題? – dasblinkenlight

+0

你想在這裏解決什麼_specific_問題? 'Concat()'方法或像'Concat()'一樣工作的任何方法都需要一個代表你的'e'值的'IEnumerable'對象。你關心的是這個對象是一個數組還是其他的東西?爲什麼數組如此糟糕?很難理解你實際上想要解決什麼問題,並且缺乏清楚地表明目標的良好[mcve],問題在於恕我直言,不清楚。 –

回答

0

有趣。首先,您不能將元素添加到IEnumerable,因爲例如,並非所有IEnumerable都是集合。例如,爲了達到您想要的效果,您最終需要將IEnumerable轉換爲List之類的內容。

我猜你正在尋找擴展方法,這是一種可能的解決方案,我可以計算出:

public class Entity 
{ 
    public IEnumerable<Entity> SubEntities { get; set; } 
} 

public static class EnumerableExtensions 
{ 

    public static IEnumerable<T> SomeBuiltInFunc<T>(this IEnumerable<T> enumerable, T item) 
    { 
     var list = enumerable.ToList(); 
     list.Add(item); 
     return list; 
    } 

} 

...那麼你可以這樣調用它:

IEnumerable<Entity> myEntities = new List<Entity>(); 
var entity = new Entity(); 
myEntities = myEntities.SelectMany(e => e.SubEntities.SomeBuiltInFunc(entity)); 

取注意我將myEntity更改爲myEntities,因爲SelectMany()是從IEnumerable<T>內置的擴展方法。另外,如果你需要一個完整的IEnumerable<T>作爲參數傳遞給您的BuiltInFunc(),只需將其更改爲類似:

public static IEnumerable<T> SomeBuiltInFunc<T>(this IEnumerable<T> enumerable, IEnumerable<T> item) 
{ 
    var list = enumerable.ToList(); 
    list.AddRange(item); 
    return list; 
} 

...那麼現在:

IEnumerable<Entity> myEntities = new List<Entity>(); 
var entity = new Entity(); 
myEntities = myEntities.SelectMany(e => e.SubEntities.SomeBuiltInFunc(myEntities)); 

最後更改的名稱SomeBuiltInFunc(),因爲它實際上不是內置的。


我只是想弄清楚這種解決方案的問題是,我們可能不會保留原來的具體類型IEnumerable的。

雖然使用接口的想法並不關心實現細節(具體類型是什麼),但可能會出現這種情況,它會改變具體類型。所以你要麼找到一種方法來解決這個問題,要麼小心這是否會成爲你的問題。

+0

我正在尋找替代擴展方法 – user433342

+0

@ user433342嗯,恐怕沒有這樣的事情。就我所知,使用內置方法,像你一樣使用'Concat()'確實是唯一的解決方案。爲什麼你需要擴展的備用?僅僅是爲了好奇還是你有另一種問題?也許我們可以幫助,如果是這樣的話。 – Alisson

+0

只是好奇心不好,還沒有機會通過完整的c#參考 – user433342

0

遞歸的答案是相當不錯的,我不知道如何Enumerable.repeat(即,1)進行比較,以新的[] {E}