简体   繁体   中英

IEnumerator and generics

I have a method which returns a list of elements with the type of T. I would like to parameterize the element the IEnumerator is iterating through as well (in this case it's the hardcoded myCanvas), but I'm clueless how to do it. Any help would be greatly appreciated.

public List<T> GetUIElements<T>() where T : DependencyObject
{
    List<T> elementList = new List<T>();

    System.Collections.IEnumerator ie = myCanvas.Children.GetEnumerator();
    while (ie.MoveNext())
    {
        if (ie.Current.GetType() == typeof(T))
        {
            elementList.Add((T)ie.Current);
        }
    }
    return elementList;
}

did you try with:

foreach (T obj in myCanvas.Children.OfType<T>())
  {
                ...
   }

the Panel.Children property is of type UIElementCollection , which is an IEnumerable .

This means you can rewrite the method:

    public List<T> GetUIElements<T>(IEnumerable collection) where T : DependencyObject
    {
        return collection.OfType<T>().ToList();
    }

then call it: List<MyType> list = GetUIElements<MyType>(myCanvas.Children);

To constrain it more (what I can derive from the method name), you could change the signature to:

public List<T> GetUIElements<T>(UIElementCollection collection) where T : UIElement

First off, and apologies that this does not answer your question, you could save yourself a lot of trouble and write better code like this:

using System.Linq;

public IEnumerable<T> GetUIElements<T>() where T : DependencyObject
{
    return myCanvas.Children.OfType<T>();
}

Once the code is in this form you can see that there is really no need for a function at all, so your original question might be no longer applicable.

If you still need to parameterize myCanvas , there are good news and bad news. The bad news is that you absolutely need to find a base class that has a Children property, and the WPF control hierarchy is not the most pure one. There could very well be controls that expose Children properties that are not related to each other, in which case there is not a lot you can do (you can pass in a DependencyObject and start type casting, but that's really dirty).

The good news is that there are very nice LINQ-to-WPF-trees adapters out there which can do this, and much more, without you needing to write the code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM