2016-10-05 3 views
3

Ich habe zwei IEnumerable-Objekte. Wenn eine bestimmte Bedingung erfüllt ist, muss ich jedes Element von IEnumerable zu IEnumerable bringen. Mein Code ist wie dieserElement zu IEnumerable hinzufügen <IPublishedContent>

IEnumerable<IPublishedContent> nodesTemp = posts.Take(10).ToList(); 
IEnumerable<IPublishedContent> nodes = null; 
foreach (var n in nodesTemp) 
{ 
    if (condition=true) 
    { 
     nodes.add(n);   
    } 
} 

Aber das wirft einen Fehler

: 'System.Collections.Generic.IEnumerable <Umbraco.Core.Models.IPublishedContent>' keine Definition enthält für ‚hinzufügen 'und keine Erweiterungsmethode' add 'akzeptiert ein erstes Argument vom Typ' System.Collections.Generic.IEnumerable <Umbraco.Core.Models.IPublishedContent> 'könnte gefunden werden (fehlt Ihnen eine Verwendungs-Richtlinie oder eine Assembly-Referenz?)

komplette Code als Referenz

IEnumerable<IPublishedContent> nodesTemp = posts.Take(count).ToList(); 

IEnumerable<IPublishedContent> nodes = null; 
foreach (IPublishedContent n in nodesTemp) 
{ 
    var rolename = n.GetProperty("focusedUserGroup").Value.ToString(); 
    var username = umbraco.cms.businesslogic.member.Member.GetCurrentMember().Text; 
    var flag = false; 

    if (!string.IsNullOrEmpty(rolename)) 
    { 
     var groups = rolename.Split(','); 

     foreach (var group in groups) 
     { 
      if (Roles.IsUserInRole(username, group)) 
      { 
       nodes.add(n); 
       break; 
      } 
     } 

    } 
} 
+2

Sie können "IEnumerable" nicht hinzufügen, es ist schreibgeschützt. Nimm eine "Liste" –

+0

@Div Kannst du irgendeine Arbeit vorschlagen, damit ich ein bestimmtes Element von einem IEnumerable zu einem anderen nehmen kann? – Athul

+0

@StuartLC Wie ich oben gezeigt habe, ist mein "if-Zustand" zu groß, um in eine einzige linq Query aufgenommen zu werden. – Athul

Antwort

4

Sie können dies nicht tun. Der Grund dafür ist, dass IEnumerable nur den Iterator einer Sammlung repräsentiert. Es kann Array im Speicher, wählen Sie aus der entfernten Datenbank oder sogar konstant Aufruf wie folgt sein:

IEnumerable<int> GetSomeConsts() 
{ 
    yield return 1; 
    yield return 101; 
    yield return 22; 
} 

Was können Sie tun, ist Post Iterator Ihrer ersten Kollektion zu erweitern. Zum Beispiel wie folgt aus:

bool IsCondition(IPublishedContent n) 
{ 
    var rolename = n.GetProperty("focusedUserGroup").Value.ToString(); 
    var username = umbraco.cms.businesslogic.member.Member.GetCurrentMember().Text; 

    if (!string.IsNullOrEmpty(rolename)) 
    { 
     var groups = rolename.Split(','); 

     foreach (var group in groups) 
     { 
      if (Roles.IsUserInRole(username, group)) 
      { 
       return true; 
      } 
     } 
    } 
    return false; 
} 

Dann rufen Sie einfach es wie folgt aus:

var nodes = posts.Take(count).Where(IsCondition); 
+0

Kannst du irgendeine Arbeit vorschlagen, damit ich ein bestimmtes Element von einem IEnumerable zu einem anderen nehmen kann? – Athul

+0

Ich habe meine Antwort bearbeitet. – eocron

+0

In der Tat, Sie sollten in der Lage sein, auch die End-for-Schleife in 'Return-Gruppen zu kürzen.Any (grp => Roles.IsUserInRole (username, grp));' – StuartLC

1

Ich denke, dass dies ein großartiges Beispiel dafür, was man yield return für

zB verwenden können:

public IEnumerable<IPublishedContent> Whatever(IEnmerable<IPublishedContent> nodes, int count) 
{ 
    foreach(var node in nodes.Take(count)) 
    { 
     var rolename = node.GetProperty("focusedUserGroup").Value.ToString(); 
     var username = umbraco.cms.businesslogic.member.Member.GetCurrentMember().Text; 
     if (!string.IsNullOrEmpty(rolename)) 
     { 
      var groups = rolename.Split(','); 

      foreach (var group in groups) 
      { 
       if (Roles.IsUserInRole(username, group)) 
       { 
        yield return node; //yield return allows you to create a new enumerable inline 
        break; 
       } 
      } 
     } 
    } 
} 

yield return führt Ihren Code aus, während Sie ihn aufzählen, also wenn Sie Whatever (...) aufrufen würden. Zuerst() würde es o Nur den Code durchlaufen, bis er die erste Rendite gefunden hat.

0

Es sieht so aus, als ob Sie ein IEnumerable filtern.

In solch einem Fall müssen Sie es nicht zuerst in eine Liste umwandeln, und Sie können Enumerable<T>.Where() verwenden, um es zu filtern.

So etwas sollte funktionieren:

var nodesTemp = posts.Take(10); 
var nodes = nodesTemp.Where(item => predicate(item)); 

Wo predicate(item) ist eine Funktion, die einen Parameter vom Typ nimmt IPublishedContent und gibt ein bool.

Sie können das als Lambda-Ausdruck, zum Beispiel schreiben:

var nodesTemp = posts.Take(10); 
var nodes = nodesTemp.Where(item => item.SomeProperty == someTargetValue); 

Wenn Sie nodes brauchen eher eine Liste zu sein als ein IEnumerable<IPublishedContent>, können Sie es in eine Liste drehen:

var nodes = nodesTemp.Where(item => item.SomeProperty == someTargetValue).ToList(); 

An dieser Stelle brauchen Sie wahrscheinlich nicht wirklich nodesTemp (es sei denn, Sie verwenden es für Debugging-Zwecke):

Verwandte Themen