2010-09-02 1 views
8

У меня есть класс IEnumerable<T>, где я хочу иметь разные свойства, обеспечивающие отфильтрованный доступ IEnumerable<T>.Возможно ли иметь свойство IEnumerable <T>?

Так, например:

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

Является ли это, как это должно быть? Просто не уверен, об этом полностью.

Спасибо.

ответ

11

Конечно, но вы можете записать его в виде

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

, который делает ту же самую вещь.

+0

+1 для выразительности. – Cumbayah

+0

Спасибо, да, это было немного шелушатся в моем сознании. Теперь я вижу это ясно. –

+0

WTG w/LINQ FTW. – Randolpho

2

Конечно, это должно работать (насколько я вижу), хотя решение @ mquander может быть чуть более элегантным.

1

Это действительный, но избыточный я думаю. Если вы хотите, чтобы выставить строго типизированный список фигур:

public class Shape 
{ 

} 

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


} 

List<T> класс реализует IEnumerable.

+0

Недостатком этого является то, что он предоставляет ваш список внешним влияниям. –

+0

Вам нужен тип возврата для вашего второго имущества. –

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

Вам не хватало get/круглые скобки, чтобы сделать его способом. Также что такое Box, вы имели в виду ShapeType.Box? Также возможно переименовать его в OnlyBoxes, кажется более описательным.

+0

Никто меня не проголосует, моя репутация хорошая, как есть. –

+0

Спасибо, я проголосовал за вас. Я написал такой код, потому что я не использовал VS и не хотел писать все это. –

1

Лично я считаю, что ваше имущество OnlyBox является излишним. Поскольку пользователи вашего класса всегда будут иметь возможность использовать Linq, как показано ниже, с такой же производительностью. Так что если вы не можете сделать это лучше, чем методы Linq, я думаю, что это прекрасно, чтобы оставить его пользователю класса, как:

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

Но если вы хотите, свойство, вместо:

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

вы могли бы написать:

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

Спасибо, идея была в том, что это упрощено, но на самом деле код для фильтрации очень уродлив, потому что это оболочка для неуправляемого класса. Поэтому хотелось сделать его немного более высоким для пользователей и меня. –

1

более LINQ, как мода будет предоставлять метод для вашей коллекции:

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

или только что пользователи делают оговорку Где:

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

В противном случае, ничего плохого в IEnumerable как свойство (имея в виду свойства должны быть так просто они редко бросают исключения).

0

Да. То, что у вас есть, хорошо. Вы можете сделать преобразование в lambda-based, если вы предпочитаете его выразительность, хотя версия лямбда может иногда быть менее результативной (не так много, что я бы изменил версию лямбды до 2.0, если она не оказалась проблематичной, но достаточно, чтобы я мог 't изменить совершенно хороший стиль 2.0 на лямбда-основе, если это не сделало его лот более выразительным).