【问题标题】:How to iterate a C# class look for all instances of a specific type, then calling a method on each instance如何迭代 C# 类查找特定类型的所有实例,然后在每个实例上调用方法
【发布时间】:2011-09-03 01:11:12
【问题描述】:

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

我有这样的课:

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()
    }    
}     

这可以吗?我已经能够获取 Control 类的所有元数据,但这仅与类型有关,与特定实例无关。

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

感谢您的帮助。

【问题讨论】:

  • 对不起,我应该提到我希望 DrawAll() 方法与 Control 实例在同一个类中。

标签: c# reflection methods field


【解决方案1】:
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 信息,我会将其标记为答案。我实际上将使用它来迭代从特定基类派生的所有实例,因此这也回答了我的另一个问题。
【解决方案2】:
var props = typeof(Overlay).GetProperties().OfType<Control>();

【讨论】:

  • +1 相信您甚至可以将其缩短为 typeof(Overlay).GetProperties().OfType(typeof(Control));
  • @pickypg:好点,我睡着了,虽然它是 OfType()
  • 这就是我从记忆中输入的结果:)。毕竟没那么困! :)
【解决方案3】:
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() 添加额外的返回值类型检查。

【讨论】:

    猜你喜欢
    • 2012-03-20
    • 1970-01-01
    • 2015-08-14
    • 2014-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多