IE分子和泛型

本文关键字:泛型 IE | 更新日期: 2023-09-27 18:26:47

我有一个方法,它返回一个类型为T的元素列表。我也想参数化IEnumerator正在迭代的元素(在这种情况下是硬编码的myCanvas),但我不知道如何做到这一点。如果有任何帮助,我们将不胜感激。

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

IE分子和泛型

Panel.Children属性的类型为UIElementCollection,即IEnumerable

这意味着您可以重写方法:

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

然后称之为:List<MyType> list = GetUIElements<MyType>(myCanvas.Children);

为了更多地约束它(我可以从方法名称中得到什么),您可以将签名更改为:

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

您尝试过使用吗

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

首先,很抱歉这不能回答您的问题,您可以省去很多麻烦,并编写这样更好的代码:

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

一旦代码以这种形式出现,您可以看到实际上根本不需要函数,因此您最初的问题可能不再适用。

如果您仍然需要参数化myCanvas,那么有好消息也有坏消息。坏消息是,您绝对需要找到一个具有Children属性的基类,而WPF控件层次结构并不是最纯的。很可能有一些控件公开了彼此不相关的Children属性,在这种情况下,您可以做的事情不多(您可以传入DependencyObject并开始类型转换,但这真的很糟糕)。

好消息是,有非常好的LINQ到WPF树适配器可以做到这一点,甚至更多,而无需编写代码。