2017-05-16 3 views
1

Aus Neugier möchte ich ein Element zu einem Enumerable innerhalb eines Linq-Flusses hinzufügen, ohne den Fluss zu beenden oder das einzelne Element auf ein Array zu übertragen.Einzelnes Element in der Linq-Anweisung anhängen

Anstatt also diese:

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

Ich möchte einen anderen Befehl, wo ich würde nicht das einzige Element in ein Array wickeln müssen:

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

oder

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

oder

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

Jedes Konstrukt in der Sprache, die ich momentan vermisse, könnte dies tun, ohne eine neue benutzerdefinierte Funktion oder Erweiterungsmethode zu erstellen.

+0

Es ist nicht wirklich stark genug, um eine Antwort zu sein, aber man kann 'verwenden Enumerable.Repeat (e, 1) 'um den Aufbau eines Arrays technisch zu vermeiden. – recursive

+2

Sie müssen dazu Ihre eigene Erweiterungsmethode schreiben. 'Enumerable.Repeat' ist weniger lesbar und Sie brauchen auch' Concat'.Was ist überhaupt mit Erweiterungsmethoden falsch? – dasblinkenlight

+0

Was _spezifisches_ Problem versuchen Sie hier zu lösen? Die 'Concat()' Methode oder irgendeine Methode, die wie 'Concat()' funktioniert, benötigt ein 'IEnumerable' Objekt, das Ihren' e' Wert darstellt. Was kümmert es dich, ob dieses Objekt ein Array oder etwas anderes ist? Warum ist ein Array so schlecht? Es ist schwer genug zu verstehen, welches Problem du eigentlich lösen willst, und es fehlt ein gutes [mcve], das das Ziel klar illustriert, die Frage ist IMHO, außer dass es unklar ist. –

Antwort

0

Interessant. Zuallererst können Sie keine Elemente zu IEnumerable hinzufügen, da beispielsweise nicht alle IEnumerable Sammlungen sind. Um das zu erreichen, was Sie wollen, müssen Sie das IEnumerable in etwas wie zB List konvertieren.

Ich denke, Sie sind für Erweiterungsmethoden suchen, die eine mögliche Lösung ist, ich herausfinden konnte:

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; 
    } 

} 

... dann sind Sie es so nennen könnte:

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

Nehmen Hinweis Ich habe Ihre myEntity zu myEntities geändert, weil SelectMany() eine integrierte Erweiterungsmethode von IEnumerable<T> ist. Auch, wenn Sie benötigen ein ganzes IEnumerable<T> als Argument zu Ihrem BuiltInFunc() passieren, es ist nur etwas ändern wie:

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

... dann jetzt:

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

Schließlich ändern Sie den Namen der SomeBuiltInFunc(), da es nicht wirklich eingebaut ist.


Ich möchte nur klar das Problem mit dieser Lösung machen ist, könnten wir nicht den ursprünglichen konkreten Typ des IEnumerable bewahren.

Während die Idee mit Schnittstellen arbeitet haupt nicht über die Details der Implementierung kümmern (was die konkrete Art ist), kann es Situationen geben, in denen es Unterschied macht die konkrete Art zu verändern. So finden Sie entweder einen Weg, um dies zu lösen, oder seien Sie vorsichtig, ob dies ein Problem für Sie wäre oder nicht.

+0

Ich suche eine Alternative zu Erweiterungsmethoden – user433342

+0

@ user433342 hmm, ich fürchte, es gibt keine solche Sache. Mit den eingebauten Methoden ist die Verwendung von 'Concat()' wie Sie tatsächlich die einzige Lösung, soweit ich weiß. Warum brauchen Sie eine Alternative zu Erweiterungen? Ist es nur aus Neugier oder hast du ein anderes Problem? Vielleicht könnten wir helfen, wenn das der Fall wäre. – Alisson

+0

Nein, nur Neugier, hatte keine Chance, durch das Patent zu gehen C# Referenz – user433342

0

Antwort der rekursiven war ziemlich gut, ich frage mich, wie Enumerable.repeat (e, 1) vergleicht, um neue [] {e}

Verwandte Themen