You can make things more concise with LINQ. Here's one way that should work: List<Control> getControls(Control container, Rectangle rect, bool bContained = false) { rect = RectangleToClient(rect); return (from Control ctl in container.Controls where rect.IntersectsWith(ctl.Bounds) == bContained let ctls = new List<Control> { ctl }.Union(ctl.Controls.OfType<Control>()) select ctls).SelectMany(x => x).ToList(); } This basically does the same thing, filters the collection according to `bContained`. Creates a collection of lists that each contain the parent control and its sub-controls. Then flattens them into one list.