Reputation: 331370
I have a class that's IEnumerable<T>
where I want to have different properties that provides a filtered IEnumerable<T>
access.
So for instance:
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;
}
}
}
Is this how it should be? Just not sure, about it completely.
Thanks.
Upvotes: 7
Views: 1534
Reputation: 113352
Yep. What you have is good. You can do convert to lambda-based if you prefer its expressiveness, though the lambda version can sometimes be less performant (not so much that I'd change a lambda version to 2.0 style unless it proved problematic, but enough that I wouldn't change a perfectly good 2.0 style to lambda-based unless it made it a lot more expressive).
Upvotes: 0
Reputation: 68737
class ShapeCollection : IEnumerable<Shape>
{
public IEnumerable<Shape> OnlyBoxes
{
get { return this.Where(s => s.ShapeType == Box); }
}
}
You were missing the get
/parenthesis to make it a method. Also what is Box
, did you mean ShapeType.Box
? Also maybe rename it to OnlyBoxes
, seems more descriptive.
Upvotes: 4
Reputation: 72005
Sure, but you might want to rewrite it as
public IEnumerable<Shape> OnlyBox
{
get { return this.Where(x => x.ShapeType == ShapeType.Box); }
}
which does the exact same thing.
Upvotes: 10
Reputation: 64118
A more LINQ like fashion would be providing a method for your Collection:
public IEnumerable<Shape> Boxes()
{
return this.Where(ss => ss.ShapeType == ShapeType.Box);
}
Or just having users do a Where clause:
// gather boxes
var query = from shape in shapes
where shape.ShapeType == ShapeType.Box
select shape;
Otherwise, nothing wrong with IEnumerable as a property (keeping in mind properties should be so simple they rarely throw exceptions).
Upvotes: 1
Reputation: 17792
Personally, I believe your OnlyBox
property is redundant. Because the users of your class will always have the option to use Linq like the following with the same performance. So unless you can do it better than the Linq methods, I think it is fine to leave it to the user of the class like:
var filtered = shapeCol.Where(s => s.ShapeType == Box);
But if you want a property, instead of:
foreach(var s in this)
{
if (s.ShapeType == Box)
yield return s;
}
you could write:
return this.Where(s => s.ShapeType == Box);
Upvotes: 1
Reputation: 34810
This is valid, but redundant I think. If you want to expose a strongly-typed list of Shapes:
public class Shape
{
}
public class SomethingThatHasShapes
{
public List<Shape> Shapes { get; set; }
public Boxes
{
get { return Shapes.Where(s => s.ShapeType = ShapeType.Box); }
}
}
The List<T>
class implements IEnumerable.
Upvotes: 1
Reputation: 158379
Sure, that should work (as far as I can see) even though @mquander's solution might be a tad more elegant.
Upvotes: 2