开发者

Is it possible to have a property that is IEnumerable<T>?

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 ret开发者_开发技巧urn s;
       }
   }
}

Is this how it should be? Just not sure, about it completely.

Thanks.


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.


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.


Sure, that should work (as far as I can see) even though @mquander's solution might be a tad more elegant.


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.


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


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).


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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜