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

时间:2021-03-07 16:24:18

I have a situation in a WebForm where I need to recurse throguh the control tree to find all controls that implement a given interface.

我在WebForm中有一种情况,我需要在控制树中执行,以找到实现给定接口的所有控件。

How would I do this?

我该怎么做?

I have tried writing an extension method like this

我试过写这样的扩展方法

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

But it does not like the cast to T on line 7. I also thought about trying the as operator but that doesn't work with interfaces.

但是它不喜欢第7行的T转换。我也考虑过尝试使用as运算符,但这不适用于接口。

I saw Scott Hanselmans disucssion but could not glean anything useful from it.

我看到了斯科特汉塞尔曼斯的耻辱,但却无法收集任何有用的信息。

Can anyone give me any pointers. Thanks.

任何人都可以给我任何指示。谢谢。

Greg

3 个解决方案

#1


I think you need to split this method into 2 parts

我认为你需要将这个方法分成两部分

  1. Find Controls recursively
  2. 递归查找控件

  3. Find Controls implementing the interface based off of #1
  4. 查找控件实现基于#1的接口

Here is #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;
        }
    }
}

Now to get all controls of a type, use the OfType extension method

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

var all = someControl.FindAllControls().OfType<ISomeInterface>();

#2


I would use the as keyword.

我会使用as关键字。

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


Is the cast really necessary? If you have a control implementing T, it should not be. Also, take a look at the is keyword:

演员真的有必要吗?如果你有一个控件实现T,它不应该。另外,看看is关键字:

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

#1


I think you need to split this method into 2 parts

我认为你需要将这个方法分成两部分

  1. Find Controls recursively
  2. 递归查找控件

  3. Find Controls implementing the interface based off of #1
  4. 查找控件实现基于#1的接口

Here is #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;
        }
    }
}

Now to get all controls of a type, use the OfType extension method

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

var all = someControl.FindAllControls().OfType<ISomeInterface>();

#2


I would use the as keyword.

我会使用as关键字。

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


Is the cast really necessary? If you have a control implementing T, it should not be. Also, take a look at the is keyword:

演员真的有必要吗?如果你有一个控件实现T,它不应该。另外,看看is关键字:

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