tags:

views:

120

answers:

3

Hi,
I have this code and i need to be able to search through different lists of HierarchyItems and return a list of the correct type
i.e. Hierarchy h = new Hierarchy();
//add a load of items of HierarchyItemA type;
List<HierarchyItemA> results = h.Search("text");

CODE:

public class Hierarchy
{
    private List<HierarchyItem> items;

    public Hierarchy()
    {
        items = new List<T>();
    }
    public void AddItem(HierarchyItem item)
    {
        items.Add(item);
    }
    public List<T> Search(string searchText)
    {
        List<T> results = new List<T>();
        foreach (HierarchyItem item in items)
        {
            if (item.DisplayText().ToLower().Contains(searchText.ToLower()))
            {
                results.Add(item);
            }
        }
        return results;
    }
}
public abstract class HierarchyItem
{
    public string DisplayText()
    {
        //returns a string
    }
}
public class HierarchyItemA : HierarchyItem
{
    //do whatever
}
public class HierarchyItemB : HierarchyItem
{
    //do whatever
}

Cheers

EDIT: there are several hierarchies each one only has one type in it. the Hierarchy.Search(text) should return a list containing items of the correct type (correct being of type A or B)

+2  A: 

Okay, I think I understand what you're trying to do now. Thanks for clarifying.

First, you need to declare the class Hierarchy as generic by replacing public class Hierarchy with public class Hierarchy<T>. We'll also put a constraint on it that T must be a HierarchyItem.

public class Hierarchy<T> where T : HierarchyItem

We'll replace private List<HierarchyItem> items with

private List<T> items;

and public void AddItem(HierarchyItem item) with

public void AddItem(T item)

And finally, the line foreach (HierarchyItem item in items) in the method search should be replaced by

foreach(T item in items).

Thus, we end up with

public class Hierarchy<T> where T: HierarchyItem {
    List<T> items;

    public Hierarchy() {
        items = new List<T>();
    }
    public void AddItem(T item) {
        items.Add(item);
    }
    public List<T> Search(string searchText) {
        List<T> results = new List<T>();
        foreach (T item in items) {
            if (item.DisplayText().ToLower().Contains(searchText.ToLower())) {
                results.Add(item);
            }
        }
        return results;
    }
}

And that should be what you're seeking.

Jason
you sir! are a genius. thank you very much
harryovers
A: 

I think what you mean is this, however Jason's answer is just as correct.

 public List<T> Search(string searchText) where T : HierarchyItem
    {
        List<T> results = new List<T>();
        foreach (HierarchyItem item in items)
        {
            if (item.DisplayText().ToLower().Contains(searchText.ToLower()))
            {
                 T castedItem = item as T;
                 if(castedItem != null )
                      results.Add(item);
            }
        }

        return results; 
    }
Stan R.
Error: The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint
harryovers
@harryovers, sorry forgot to add a constraint..edited answer.
Stan R.
A: 

Wow, way to much code for those other answers. This is a one line problem peeps.

public List<T> Search(string searchText) where T: HirearchyItem
    {
        return Items.OfType<T>().Where(t => t.DisplayText.ToUpper().Contains(searchText.ToUpper())).ToList<T>();   
    }

But if part of the design is that any Hirearchy can only contain items of a single HirearchyItem type, then you may want to make Hirearchy itself a generic class.

Truth be told, Hirearchy is really just a wrapper for a List, why don't you just create an interface for DisplayText and an extention method for List when T implements IHasDisplayText that performs this search?

tom.dietrich
yeah, that is if he is using .NET 3.5, which he didn't specify.
Stan R.
If he isn't, then he should be. 2.0 blows monkey chunks.
tom.dietrich
Note: One liners aren't better, readable code (not for you, but for others) is preferred!
PoweRoy