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

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

감사합니다. 두 가지 스타일의 쿼리에 대해 두 가지 답변을 제공합니다. 둘 다 좋습니다. 어느 쪽이 받아 들여지는지 모르겠습니다 :) – Peter17

0

, 당신은 모두 반사를 방지 할 수 있습니다, 그리고 Controls 컬렉션을 통해 단지 루프, 뭔가 같은 :

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

또는 LINQ가 적용되지 않은 변종

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 컬렉션을 보는 것과 다릅니다. 모든 컨트롤이 필드가 아니며 모든 필드가 Controls 컬렉션에있는 것은 아닙니다 (컨트롤 인 경우에도 해당). 그래서 유효한 대답이지만 뭔가 다른 것을합니다. –

+0

나는 절대적으로 동의하지만, 반사는 일반적으로 과잉이 될 수 있습니다. 나는 OP가 분야에 대해 명백하다는 것을 인정하지만, 누군가가 먼저 그것에 비틀 거리면 나는이 대답을 남겨 둘 것입니다. BTW, int 필드는 controls 컬렉션에 없지만 어떻게 컨트롤이 필드가 될 수 있습니까? – SWeko