如何查找实现接口并调用方法的所有对象

Wil*_*lem 1 .net c# reflection wpf interface

我有一个UserControl有几个孩子UserControl的,而那些UserControl有孩子的 UserControl。

考虑一下:

MainUserControl
  TabControl
    TabItem
      UserControl
        UserControl
          UserControl : ISomeInterface
    TabItem
      UserControl
        UserControl
          UserControl : ISomeInterface
    TabItem
      UserControl
        UserControl
          UserControl : ISomeInterface
    TabItem
      UserControl
        UserControl
          UserControl : ISomeInterface
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止所拥有的,但没有发现ISomeInterface

PropertyInfo[] properties = MainUserControl.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
    if (typeof(ISomeInterface).IsAssignableFrom(property.PropertyType))
    {
        property.GetType().InvokeMember("SomeMethod", BindingFlags.InvokeMethod, null, null, null);
    }
}
Run Code Online (Sandbox Code Playgroud)

是否有可能通过反射UserControlMainUserControl该实现中找到所有 childISomeInterfacevoid SomeMethod()在该接口上调用一个方法()?

Mat*_*son 5

您将需要递归遍历 MainUserControl 中的所有子控件。

这是您可以使用的辅助方法:

/// <summary>
/// Recursively lists all controls under a specified parent control.
/// Child controls are listed before their parents.
/// </summary>
/// <param name="parent">The control for which all child controls are returned</param>
/// <returns>Returns a sequence of all controls on the control or any of its children.</returns>

public static IEnumerable<Control> AllControls(Control parent)
{
    if (parent == null)
    {
        throw new ArgumentNullException("parent");
    }

    foreach (Control control in parent.Controls)
    {
        foreach (Control child in AllControls(control))
        {
            yield return child;
        }

        yield return control;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

foreach (var control in AllControls(MainUserControl))
{
    PropertyInfo[] properties = control.GetType().GetProperties();
    ... Your loop iterating over properties
Run Code Online (Sandbox Code Playgroud)

或者(如果这对你有用,那就更好了,因为它简单得多):

foreach (var control in AllControls(MainUserControl))
{
    var someInterface = control as ISomeInterface;

    if (someInterface != null)
    {
        someInterface.SomeMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,使用 Linq(需using System.Linq要这样做):

foreach (var control in AllControls(MainUserControl).OfType<ISomeInterface>())
    control.SomeMethod();
Run Code Online (Sandbox Code Playgroud)

这似乎是最好的。:)

  • 也许您可以使用 `is` 运算符进行添加。OP 似乎正朝着使用反射的方向发展,而动态转换更容易(也更便宜)(或者我是否也错过了一些东西?) (2认同)