如何迭代C#类以查找特定类型的所有实例,然后对每个实例调用一个方法

4

通过反射技术,是否可以迭代对象的所有字段并在每个字段上调用方法。

我有一个类如下:

public class Overlay
{
    public Control control1;
    public Control control2;
}

我希望有一种类似如下的方法:

我想要一个这样的方法:

public void DrawAll()
{
    Controls[] controls = "All instances of Control"
    foreach (Control control in Controls)
    {
        control.Draw()
    }    
}     

这可以做到吗?我已经能够获取控件类上的所有元数据,但这仅涉及类型而不是特定实例。

我知道这似乎很奇怪,但我有我的理由。我正在使用Unity 3D,每个控件实际上都是由编辑器实例化的GUI控件。

感谢任何帮助。


抱歉,我应该提到我希望方法DrawAll()在同一个类中与Control实例。 - Richard Adams
3个回答

3
public class Program
{
    static void Main(string[] args)
    {
        Overlay overlay = new Overlay();
        foreach (FieldInfo field in overlay.GetType().GetFields())
        {
            if(typeof(Control).IsAssignableFrom(field.FieldType))
            {
                Control c = field.GetValue(overlay) as Control;
                if(c != null)
                    c.Draw();
            }
        }
    }
}

注意:这将过滤掉类中不是控件的字段。此外,IsAssignableFrom将对继承自Control的任何字段类型返回true,假设您希望处理这些字段。

这对我很有效。由于提供了额外的IsAssignableFrom信息,我将把它标记为答案。实际上,我将使用它来迭代所有从特定基类派生的实例,因此这也回答了我的另一个问题。 - Richard Adams

2
var props = typeof(Overlay).GetProperties().OfType<Control>();

+1 相信你甚至可以将其缩短为 typeof(Overlay).GetProperties().OfType(typeof(Control)); - pickypg
1
@pickypg:说得好,我有点困了,不过它是OfType<Control>()。 - bevacqua
这就是我从记忆中打字的结果:)。终究还是没那么困!:) - pickypg

1
Overlay obj = new Overlay();
Type t = typeof(Overlay);
FieldInfo[] fields = t.GetFields();
foreach (FieldInfo info in fields)
{
    Control c = (Control)info.GetValue(obj);
    c.Draw();
}

请注意,如果您的对象还没有Control字段,则需要通过GetValue()返回值的类型添加额外的检查。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接