2010-09-02 8 views
8

Ich habe eine Klasse, die IEnumerable<T> ist, wo ich verschiedene Eigenschaften haben wollen, die eine gefilterte IEnumerable<T> Zugang.Ist es möglich, eine Eigenschaft zu haben, die IEnumerable <T> ist?

So zum Beispiel:

class Shape 
    ShapeType = Box/Sphere/Pyramid 

class ShapeCollection : IEnumerable<Shape> 
{ 
    public IEnumerable<Shape> OnlyBox 
    { 
     foreach(var s in this) 
     { 
      if (s.ShapeType == Box) 
       yield return s; 
     } 
    } 
} 

Ist dies, wie es sein sollte? Nur nicht sicher, darüber komplett.

Danke.

Antwort

11

Sicher, aber man könnte es als

public IEnumerable<Shape> OnlyBox 
{ 
    get { return this.Where(x => x.ShapeType == ShapeType.Box); } 
} 

, die genau die gleiche Sache tut umschreiben wollen.

+0

+1 für Ausdruckskraft. – Cumbayah

+0

Danke, ja das war ein bisschen flockig in meinem Kopf. Jetzt kann ich es deutlich sehen. –

+0

WTG mit LINQ FTW. – Randolpho

2

Sicher, das sollte (soweit ich sehen kann) arbeiten, obwohl @ mquander Lösung könnte ein bisschen mehr elegant sein.

1

Dies ist gültig, aber überflüssig denke ich.

public class Shape 
{ 

} 

public class SomethingThatHasShapes 
{ 
    public List<Shape> Shapes { get; set; } 
    public Boxes 
    { 
     get { return Shapes.Where(s => s.ShapeType = ShapeType.Box); } 
    } 


} 

Die List<T> Klasse implementiert IEnumerable: Wenn Sie eine stark typisierte Liste von Formen verfügbar machen möchten.

+0

Der Nachteil davon ist, dass es Ihre Liste äußeren Einflüssen aussetzt. –

+0

Sie benötigen einen Rückgabetyp für Ihre zweite Eigenschaft. –

4
class ShapeCollection : IEnumerable<Shape> 
{ 
    public IEnumerable<Shape> OnlyBoxes 
    { 
     get { return this.Where(s => s.ShapeType == Box); } 
    } 
} 

Sie fehlten die get/Klammer es eine Methode zu machen. Auch was ist Box, meinst du ShapeType.Box? Auch vielleicht umbenennen sie zu OnlyBoxes, scheint beschreibender.

+0

Niemand stimmt mich ab, mein Ruf ist so gut wie er ist. –

+0

Danke ich habe dich gewählt. Ich habe den Code so geschrieben, weil ich VS nicht benutzt habe und nicht das ganze schreiben wollte. –

1

Ich persönlich glaube, Ihre OnlyBox Eigenschaft redundant ist. Weil die Benutzer Ihrer Klasse immer die Option haben, Linq wie die folgenden mit der gleichen Leistung zu verwenden. Also, wenn Sie es besser als die Linq Methoden tun, ich denke, es ist in Ordnung, es dem Benutzer der Klasse zu verlassen, wie:

var filtered = shapeCol.Where(s => s.ShapeType == Box); 

Aber wenn Sie möchten, eine Eigenschaft, statt:

foreach(var s in this) 
{ 
    if (s.ShapeType == Box) 
     yield return s; 
} 

Sie schreiben kann:

return this.Where(s => s.ShapeType == Box); 
+0

Danke, die Idee war, weil dies vereinfacht ist, aber in Wirklichkeit ist der Code zum Filtern sehr hässlich, weil dies ein Wrapper für die nicht verwaltete Klasse ist. Ich wollte es also für die Benutzer und mich etwas höher machen. –

1

ein LINQ wie Art und Weise, ein Verfahren für die Sammlung zur Verfügung stellen würde:

public IEnumerable<Shape> Boxes() 
{ 
    return this.Where(ss => ss.ShapeType == ShapeType.Box); 
} 

Oder nur mit Benutzern tun, um eine Where-Klausel:

// gather boxes 
var query = from shape in shapes 
      where shape.ShapeType == ShapeType.Box 
      select shape; 

Sonst nichts falsch mit IEnumerable als Eigenschaft (unter Berücksichtigung der Tatsache Eigenschaften sollte so einfach sein, sie nur selten Ausnahmen werfen).

0

Yep. Was du hast, ist gut. Sie können tun konvertieren Lambda-basierte, wenn Sie seine Ausdruckskraft bevorzugen, wenn die Lambda-Versionkann manchmal weniger performant sein (nicht so sehr, dass ich eine Lambda-Version 2.0 Stil ändern würde, wenn es sich als problematisch erwiesen, aber genug, dass ich wouldn Ändern Sie nicht einen perfekt guten 2.0-Stil zu Lambda-basiert, es sei denn es machte es ein Los ausdrucksvoller).

Verwandte Themen