2011-03-02 62 views
1

我有以下代码,它是表单中的私有方法,并从表单中检索所有上下文菜单。我觉得,它并不是那么简洁,因为它应该是。将不胜感激的任何建议。检索具有指定类型的字段的值

private IEnumerable<ContextMenuStrip> GetContextMenus() 
    { 
     var type = this.GetType(); 
     var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance); 
     var contextMenus = fields.Where(f => f.GetValue(this).GetType() == typeof(ContextMenuStrip)); 
     var menus = contextMenus.Select(f=> f.GetValue(this)); 
     return menus.Cast<ContextMenuStrip>();   
    } 

回答

3

您是否乐意包含ContextMenuStrip的子类?如果是的话,我会用:

return GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
       .Select(field => field.GetValue(this)) 
       .OfType<ContextMenuStrip>(); 
+0

谢谢你的伟大答案! – Peter17 2011-03-02 11:47:52

1
var query = (from f in GetType().GetFields(
       BindingFlags.NonPublic | BindingFlags.Instance) 
      select f.GetValue(this)).OfType<ContextMenuStrip>(); 
+0

谢谢。我有两种不同风格的查询的答案。两者都很棒。我不知道应该接受哪一个。:) – Peter17 2011-03-02 11:49:51

0

如果代码是在一个形式,你可能想完全避免反射,并在Controls集合只是循环,是这样的:

var controls = from Control c in Controls.AsQueryable() 
       where c is ContextMenuStrip 
       select c; 

或un-LINQed变种

IEnumerable<ContextMenuStrip> result = new List<ContextMenuStrip>(); 
foreach (var control in Controls) 
{ 
    ContextMenuStrip menuStrip = (control as ContextMenuStrip) 
    if (menuStrip != null) 
    { 
    result.Add(menuStrip); 
    } 
} 
return result; 
+0

查看字段与查看Controls集合不同。并非所有控件都是字段,并且并非所有字段都(直接)在控件集合中(即使它们是控件)。所以一个有效的答案,但它做了一些不同的事情。 – 2011-03-02 11:55:34

+0

我绝对同意,但反思通常可能是一种矫枉过正。我承认OP对田野是明确的,但如果有人首先绊倒它,我会在这里留下这个答案。顺便说一句,一个int字段不会在控件集合中,但控件不能是一个字段? – SWeko 2011-03-02 12:09:37

相关问题