代码之家  ›  专栏  ›  技术社区  ›  Greg B

以递归方式检查接口的实现,c#

  •  3
  • Greg B  · 技术社区  · 15 年前

    我在一个WebForm中遇到了这样一种情况:我需要通过控制树递归,以查找实现给定接口的所有控件。

    我该怎么做?

    我试过写这样的扩展方法

    public static class ControlExtensions
    {
        public static List<T> FindControlsByInterface<T>(this Control control)
        {
            List<T> retval = new List<T>();
            if (control.GetType() == typeof(T))                
                retval.Add((T)control);
    
    
            foreach (Control c in control.Controls)
            {
                retval.AddRange(c.FindControlsByInterface<T>());
            }
    
            return retval;
        }
    }
    

    但它不喜欢演员 T 在第7行。 我也考虑过尝试as操作符,但这不适用于接口。

    我看见了 Scott Hanselmans disucssion 但无法从中收集任何有用的信息。

    有人能给我指点一下吗?谢谢。

    格雷戈

    3 回复  |  直到 13 年前
        1
  •  10
  •   JaredPar    15 年前

    我想你需要把这个方法分成两部分

    1. 递归查找控件
    2. 查找基于1实现接口的控件

    这里是第1章。

    public static IEnumerable<Control> FindAllControls(this Control control) {
        yield return control;
        foreach ( var child in control.Controls ) {
            foreach ( var all in child.FindAllControls() ) {
              yield return all;
            }
        }
    }
    

    现在要获取类型的所有控件,请使用OfType扩展方法

    var all = someControl.FindAllControls().OfType<ISomeInterface>();
    
        2
  •  2
  •   Yvo    15 年前

    我会用 作为 关键字。

    public static class ControlExtensions {
        public static List<T> FindControlsByInterface<T>(this Control control) where T : class
        {
            List<T> retval = new List<T>();
            T item = control as T;
            if (T != null)
                retval.Add(item);
    
            foreach (Control c in control.Controls)
                retval.AddRange(c.FindControlsByInterface<T>());
    
            return retval;
        }
    }
    
        3
  •  1
  •   DanDan    15 年前

    if (control is T)   
            retval.Add(control);