2011-03-02 59 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

相關問題