public static IEnumerable<TreeNode> LazyGetChildNodesOfObject(TreeNode current, Expression targetObject, DebugType shownType) { MemberInfo[] publicStatic = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly); MemberInfo[] publicInstance = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); MemberInfo[] nonPublicStatic = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly); MemberInfo[] nonPublicInstance = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); DebugType baseType = (DebugType)shownType.BaseType; if (baseType != null) { yield return new TreeNode( DebuggerResourceService.GetImage("Icons.16x16.Class"), StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.BaseClass}"), baseType.Name, baseType.FullName, current, newNode => baseType.FullName == "System.Object" ? null : Utils.LazyGetChildNodesOfObject(newNode, targetObject, baseType) ); } if (nonPublicInstance.Length > 0) { yield return new TreeNode( null, StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicMembers}"), string.Empty, string.Empty, current, newNode => Utils.LazyGetMembersOfObject(newNode, targetObject, nonPublicInstance) ); } if (publicStatic.Length > 0 || nonPublicStatic.Length > 0) { yield return new TreeNode( null, StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.StaticMembers}"), string.Empty, string.Empty, current, p => { var children = Utils.LazyGetMembersOfObject(p, targetObject, publicStatic); if (nonPublicStatic.Length > 0) { TreeNode nonPublicStaticNode = new TreeNode( null, StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicStaticMembers}"), string.Empty, string.Empty, p, newNode => Utils.LazyGetMembersOfObject(newNode, targetObject, nonPublicStatic) ); children = Utils.PrependNode(nonPublicStaticNode, children); } return children; } ); } DebugType iListType = (DebugType)shownType.GetInterface(typeof(IList).FullName); if (iListType != null) { yield return new IListNode(current, targetObject); } else { DebugType iEnumerableType, itemType; if (shownType.ResolveIEnumerableImplementation(out iEnumerableType, out itemType)) { yield return new IEnumerableNode(current, targetObject, itemType); } } foreach(TreeNode node in LazyGetMembersOfObject(current, targetObject, publicInstance)) { yield return node; } }
private List<ObjectGraphProperty> getProperties(Expression expression, DebugType shownType, BindingFlags flags) { List<ObjectGraphProperty> propertyList = new List<ObjectGraphProperty>(); foreach (MemberInfo memberProp in shownType.GetFieldsAndNonIndexedProperties(flags)) { if (memberProp.Name.Contains("<")) { // skip backing fields continue; } if (memberProp.DeclaringType != shownType) { // skip properties declared in the base type continue; } // ObjectGraphProperty needs an expression // to know whether it is expanded, and to evaluate Expression propExpression = expression.AppendMemberReference((IDebugMemberInfo)memberProp); // Value, IsAtomic are lazy evaluated propertyList.Add(new ObjectGraphProperty { Name = memberProp.Name, Expression = propExpression, Value = "", MemberInfo = memberProp, IsAtomic = true, TargetNode = null }); } return propertyList.Sorted(ObjectPropertyComparer.Instance); }