コード例 #1
0
        public ObjectFormattingOptions(
            MemberDisplayFormat memberFormat = MemberDisplayFormat.NoMembers,
            bool quoteStrings = true,
            bool useHexadecimalNumbers = false,
            bool includeCodePoints = false,
            int maxLineLength = Int32.MaxValue,
            int maxOutputLength = Int32.MaxValue,
            string memberIndentation = null,
            string ellipsis = null,
            string lineBreak = null)
        {
            if (!memberFormat.IsValid())
            {
                throw new ArgumentOutOfRangeException("memberFormat");
            }

            this.MemberFormat = memberFormat;
            this.QuoteStrings = quoteStrings;
            this.IncludeCodePoints = includeCodePoints;
            this.MaxOutputLength = (maxOutputLength >= 0) ? maxOutputLength : int.MaxValue;
            this.MaxLineLength = (maxLineLength >= 0) ? maxLineLength : int.MaxValue;
            this.UseHexadecimalNumbers = useHexadecimalNumbers;
            this.MemberIndentation = memberIndentation ?? "  ";
            this.Ellipsis = ellipsis ?? "...";
            this.NewLine = lineBreak ?? Environment.NewLine;
        }
コード例 #2
0
        public ObjectFormattingOptions(
            MemberDisplayFormat memberFormat = MemberDisplayFormat.NoMembers,
            bool quoteStrings          = true,
            bool useHexadecimalNumbers = false,
            bool includeCodePoints     = false,
            int maxLineLength          = Int32.MaxValue,
            int maxOutputLength        = Int32.MaxValue,
            string memberIndentation   = null,
            string ellipsis            = null,
            string lineBreak           = null)
        {
            if (!memberFormat.IsValid())
            {
                throw new ArgumentOutOfRangeException(nameof(memberFormat));
            }

            this.MemberFormat          = memberFormat;
            this.QuoteStrings          = quoteStrings;
            this.IncludeCodePoints     = includeCodePoints;
            this.MaxOutputLength       = (maxOutputLength >= 0) ? maxOutputLength : int.MaxValue;
            this.MaxLineLength         = (maxLineLength >= 0) ? maxLineLength : int.MaxValue;
            this.UseHexadecimalNumbers = useHexadecimalNumbers;
            this.MemberIndentation     = memberIndentation ?? "  ";
            this.Ellipsis = ellipsis ?? "...";
            this.NewLine  = lineBreak ?? Environment.NewLine;
        }
コード例 #3
0
 public Visitor(
     CommonObjectFormatter formatter,
     BuilderOptions builderOptions,
     CommonPrimitiveFormatterOptions primitiveOptions,
     CommonTypeNameFormatterOptions typeNameOptions,
     MemberDisplayFormat memberDisplayFormat)
 {
     _formatter           = formatter;
     _builderOptions      = builderOptions;
     _primitiveOptions    = primitiveOptions;
     _typeNameOptions     = typeNameOptions;
     _memberDisplayFormat = memberDisplayFormat;
 }
コード例 #4
0
 public Visitor(
     CommonObjectFormatter formatter,
     BuilderOptions builderOptions,
     CommonPrimitiveFormatterOptions primitiveOptions,
     CommonTypeNameFormatterOptions typeNameOptions,
     MemberDisplayFormat memberDisplayFormat)
 {
     _formatter = formatter;
     _builderOptions = builderOptions;
     _primitiveOptions = primitiveOptions;
     _typeNameOptions = typeNameOptions;
     _memberDisplayFormat = memberDisplayFormat;
 }
コード例 #5
0
 public ObjectFormattingOptions Copy(
     MemberDisplayFormat? memberFormat = null,
     bool? quoteStrings = null,
     bool? useHexadecimalNumbers = null,
     bool? includeCodePoints = null,
     int? maxLineLength = null,
     int? maxOutputLength = null,
     string memberIndentation = null,
     string ellipsis = null,
     string newLine = null)
 {
     return new ObjectFormattingOptions(
         memberFormat ?? this.MemberFormat,
         quoteStrings ?? this.QuoteStrings,
         useHexadecimalNumbers ?? this.UseHexadecimalNumbers,
         includeCodePoints ?? this.IncludeCodePoints,
         maxLineLength ?? this.MaxLineLength,
         maxOutputLength ?? this.MaxOutputLength,
         memberIndentation ?? this.MemberIndentation,
         ellipsis ?? this.Ellipsis,
         newLine ?? this.NewLine);
 }
コード例 #6
0
 internal static bool IsValid(this MemberDisplayFormat value)
 {
     return(MemberDisplayFormat.SingleLine <= value && value <= MemberDisplayFormat.Hidden);
 }
コード例 #7
0
            private Builder FormatObjectRecursive(Builder result, object obj, bool quoteStrings, MemberDisplayFormat memberFormat, out string name)
            {
                name = null;
                string primitive = _language.FormatPrimitive(obj, quoteStrings, _options.IncludeCodePoints, _options.UseHexadecimalNumbers);
                if (primitive != null)
                {
                    result.Append(primitive);
                    return result;
                }

                object originalObj = obj;
                Type originalType = originalObj.GetType();

                //
                // Override KeyValuePair<,>.ToString() to get better dictionary elements formatting:
                //
                // { { format(key), format(value) }, ... }
                // instead of
                // { [key.ToString(), value.ToString()], ... } 
                //
                // This is more general than overriding Dictionary<,> debugger proxy attribute since it applies on all
                // types that return an array of KeyValuePair in their DebuggerDisplay to display items.
                //
                if (originalType.IsGenericType && originalType.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
                {
                    if (memberFormat != MemberDisplayFormat.InlineValue)
                    {
                        result.Append(_language.FormatTypeName(originalType, _options));
                        result.Append(' ');
                    }

                    FormatKeyValuePair(result, originalObj);
                    return result;
                }

                if (originalType.IsArray)
                {
                    if (!VisitedObjects.Add(originalObj))
                    {
                        result.AppendInfiniteRecursionMarker();
                        return result;
                    }

                    FormatArray(result, (Array)originalObj, inline: memberFormat != MemberDisplayFormat.List);

                    VisitedObjects.Remove(originalObj);
                    return result;
                }

                DebuggerDisplayAttribute debuggerDisplay = GetApplicableDebuggerDisplayAttribute(originalType);
                if (debuggerDisplay != null)
                {
                    name = debuggerDisplay.Name;
                }

                bool suppressMembers = false;

                //
                // TypeName(count) for ICollection implementers
                // or
                // TypeName([[DebuggerDisplay.Value]])        // Inline
                // [[DebuggerDisplay.Value]]                  // InlineValue
                // or
                // [[ToString()]] if ToString overridden
                // or
                // TypeName 
                // 
                ICollection collection;
                if ((collection = originalObj as ICollection) != null)
                {
                    FormatCollectionHeader(result, collection);
                }
                else if (debuggerDisplay != null && !String.IsNullOrEmpty(debuggerDisplay.Value))
                {
                    if (memberFormat != MemberDisplayFormat.InlineValue)
                    {
                        result.Append(_language.FormatTypeName(originalType, _options));
                        result.Append('(');
                    }

                    FormatWithEmbeddedExpressions(result, debuggerDisplay.Value, originalObj);

                    if (memberFormat != MemberDisplayFormat.InlineValue)
                    {
                        result.Append(')');
                    }

                    suppressMembers = true;
                }
                else if (HasOverriddenToString(originalType))
                {
                    ObjectToString(result, originalObj);
                    suppressMembers = true;
                }
                else
                {
                    result.Append(_language.FormatTypeName(originalType, _options));
                }

                if (memberFormat == MemberDisplayFormat.NoMembers)
                {
                    return result;
                }

                bool includeNonPublic = memberFormat == MemberDisplayFormat.List;
                object proxy = GetDebuggerTypeProxy(obj);
                if (proxy != null)
                {
                    obj = proxy;
                    includeNonPublic = false;
                    suppressMembers = false;
                }

                if (memberFormat != MemberDisplayFormat.List && suppressMembers)
                {
                    return result;
                }

                // TODO (tomat): we should not use recursion
                RuntimeHelpers.EnsureSufficientExecutionStack();

                result.Append(' ');

                if (!VisitedObjects.Add(originalObj))
                {
                    result.AppendInfiniteRecursionMarker();
                    return result;
                }

                // handle special types only if a proxy isn't defined
                if (proxy == null)
                {
                    IDictionary dictionary;
                    if ((dictionary = obj as IDictionary) != null)
                    {
                        FormatDictionary(result, dictionary, inline: memberFormat != MemberDisplayFormat.List);
                        return result;
                    }

                    IEnumerable enumerable;
                    if ((enumerable = obj as IEnumerable) != null)
                    {
                        FormatSequence(result, enumerable, inline: memberFormat != MemberDisplayFormat.List);
                        return result;
                    }
                }

                FormatObjectMembers(result, obj, originalType, includeNonPublic, inline: memberFormat != MemberDisplayFormat.List);

                VisitedObjects.Remove(obj);

                return result;
            }
コード例 #8
0
            private Builder FormatObjectRecursive(Builder result, object obj, bool isRoot, out string debuggerDisplayName)
            {
                // TODO (https://github.com/dotnet/roslyn/issues/6689): remove this
                if (!isRoot && _memberDisplayFormat == MemberDisplayFormat.SeparateLines)
                {
                    _memberDisplayFormat = MemberDisplayFormat.SingleLine;
                }

                debuggerDisplayName = null;
                string primitive = _formatter.PrimitiveFormatter.FormatPrimitive(obj, _primitiveOptions);

                if (primitive != null)
                {
                    result.Append(primitive);
                    return(result);
                }

                Type     type     = obj.GetType();
                TypeInfo typeInfo = type.GetTypeInfo();

                //
                // Override KeyValuePair<,>.ToString() to get better dictionary elements formatting:
                //
                // { { format(key), format(value) }, ... }
                // instead of
                // { [key.ToString(), value.ToString()], ... }
                //
                // This is more general than overriding Dictionary<,> debugger proxy attribute since it applies on all
                // types that return an array of KeyValuePair in their DebuggerDisplay to display items.
                //
                if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(KeyValuePair <,>))
                {
                    if (isRoot)
                    {
                        result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions));
                        result.Append(' ');
                    }

                    FormatKeyValuePair(result, obj);
                    return(result);
                }

                if (typeInfo.IsArray)
                {
                    if (VisitedObjects.Add(obj))
                    {
                        FormatArray(result, (Array)obj);

                        VisitedObjects.Remove(obj);
                    }
                    else
                    {
                        result.AppendInfiniteRecursionMarker();
                    }

                    return(result);
                }

                DebuggerDisplayAttribute debuggerDisplay = GetApplicableDebuggerDisplayAttribute(typeInfo);

                if (debuggerDisplay != null)
                {
                    debuggerDisplayName = debuggerDisplay.Name;
                }

                // Suppresses members if inlineMembers is true,
                // does nothing otherwise.
                bool suppressInlineMembers = false;

                //
                // TypeName(count) for ICollection implementers
                // or
                // TypeName([[DebuggerDisplay.Value]])        // Inline
                // [[DebuggerDisplay.Value]]                  // Inline && !isRoot
                // or
                // [[ToString()]] if ToString overridden
                // or
                // TypeName
                //
                ICollection collection;

                if ((collection = obj as ICollection) != null)
                {
                    FormatCollectionHeader(result, collection);
                }
                else if (debuggerDisplay != null && !string.IsNullOrEmpty(debuggerDisplay.Value))
                {
                    if (isRoot)
                    {
                        result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions));
                        result.Append('(');
                    }

                    FormatWithEmbeddedExpressions(result, debuggerDisplay.Value, obj);

                    if (isRoot)
                    {
                        result.Append(')');
                    }

                    suppressInlineMembers = true;
                }
                else if (HasOverriddenToString(typeInfo))
                {
                    ObjectToString(result, obj);
                    suppressInlineMembers = true;
                }
                else
                {
                    result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions));
                }

                MemberDisplayFormat memberFormat = _memberDisplayFormat;

                if (memberFormat == MemberDisplayFormat.Hidden)
                {
                    if (collection != null)
                    {
                        // NB: Collections specifically ignore MemberDisplayFormat.Hidden.
                        memberFormat = MemberDisplayFormat.SingleLine;
                    }
                    else
                    {
                        return(result);
                    }
                }

                bool includeNonPublic = memberFormat == MemberDisplayFormat.SeparateLines;
                bool inlineMembers    = memberFormat == MemberDisplayFormat.SingleLine;

                object proxy = GetDebuggerTypeProxy(obj);

                if (proxy != null)
                {
                    includeNonPublic      = false;
                    suppressInlineMembers = false;
                }

                if (!suppressInlineMembers || !inlineMembers)
                {
                    FormatMembers(result, obj, proxy, includeNonPublic, inlineMembers);
                }

                return(result);
            }
コード例 #9
0
            private Builder FormatWithEmbeddedExpressions(Builder result, string format, object obj)
            {
                int i = 0;

                while (i < format.Length)
                {
                    char c = format[i++];
                    if (c == '{')
                    {
                        if (i >= 2 && format[i - 2] == '\\')
                        {
                            result.Append('{');
                        }
                        else
                        {
                            int expressionEnd = format.IndexOf('}', i);

                            bool   noQuotes, callableOnly;
                            string memberName;
                            if (expressionEnd == -1 || (memberName = ParseSimpleMemberName(format, i, expressionEnd, out noQuotes, out callableOnly)) == null)
                            {
                                // the expression isn't properly formatted
                                result.Append(format, i - 1, format.Length - i + 1);
                                break;
                            }

                            MemberInfo member = ResolveMember(obj, memberName, callableOnly);
                            if (member == null)
                            {
                                result.AppendFormat(callableOnly ? "!<Method '{0}' not found>" : "!<Member '{0}' not found>", memberName);
                            }
                            else
                            {
                                Exception exception;
                                object    value = GetMemberValue(member, obj, out exception);

                                if (exception != null)
                                {
                                    FormatException(result, exception);
                                }
                                else
                                {
                                    MemberDisplayFormat             oldMemberDisplayFormat = _memberDisplayFormat;
                                    CommonPrimitiveFormatterOptions oldPrimitiveOptions    = _primitiveOptions;

                                    _memberDisplayFormat = MemberDisplayFormat.Hidden;
                                    _primitiveOptions    = new CommonPrimitiveFormatterOptions(
                                        _primitiveOptions.NumberRadix,
                                        _primitiveOptions.IncludeCharacterCodePoints,
                                        quoteStringsAndCharacters: !noQuotes,
                                        escapeNonPrintableCharacters: _primitiveOptions.EscapeNonPrintableCharacters,
                                        cultureInfo: _primitiveOptions.CultureInfo);

                                    string _;
                                    FormatObjectRecursive(result, value, isRoot: false, debuggerDisplayName: out _);

                                    _primitiveOptions    = oldPrimitiveOptions;
                                    _memberDisplayFormat = oldMemberDisplayFormat;
                                }
                            }
                            i = expressionEnd + 1;
                        }
                    }
                    else
                    {
                        result.Append(c);
                    }
                }

                return(result);
            }
コード例 #10
0
 internal static bool IsValid(this MemberDisplayFormat value)
 {
     return(value is >= MemberDisplayFormat.SingleLine and <= MemberDisplayFormat.Hidden);
 }
コード例 #11
0
            private Builder FormatWithEmbeddedExpressions(Builder result, string format, object obj)
            {
                int i = 0;
                while (i < format.Length)
                {
                    char c = format[i++];
                    if (c == '{')
                    {
                        if (i >= 2 && format[i - 2] == '\\')
                        {
                            result.Append('{');
                        }
                        else
                        {
                            int expressionEnd = format.IndexOf('}', i);

                            bool noQuotes, callableOnly;
                            string memberName;
                            if (expressionEnd == -1 || (memberName = ParseSimpleMemberName(format, i, expressionEnd, out noQuotes, out callableOnly)) == null)
                            {
                                // the expression isn't properly formatted
                                result.Append(format, i - 1, format.Length - i + 1);
                                break;
                            }

                            MemberInfo member = ResolveMember(obj, memberName, callableOnly);
                            if (member == null)
                            {
                                result.AppendFormat(callableOnly ? "!<Method '{0}' not found>" : "!<Member '{0}' not found>", memberName);
                            }
                            else
                            {
                                Exception exception;
                                object value = GetMemberValue(member, obj, out exception);

                                if (exception != null)
                                {
                                    FormatException(result, exception);
                                }
                                else
                                {
                                    MemberDisplayFormat oldMemberDisplayFormat = _memberDisplayFormat;
                                    CommonPrimitiveFormatterOptions oldPrimitiveOptions = _primitiveOptions;

                                    _memberDisplayFormat = MemberDisplayFormat.Hidden;
                                    _primitiveOptions = new CommonPrimitiveFormatterOptions(
                                        _primitiveOptions.NumberRadix,
                                        _primitiveOptions.IncludeCharacterCodePoints,
                                        quoteStringsAndCharacters: !noQuotes,
                                        escapeNonPrintableCharacters: _primitiveOptions.EscapeNonPrintableCharacters,
                                        cultureInfo: _primitiveOptions.CultureInfo);

                                    string _;
                                    FormatObjectRecursive(result, value, isRoot: false, debuggerDisplayName: out _);

                                    _primitiveOptions = oldPrimitiveOptions;
                                    _memberDisplayFormat = oldMemberDisplayFormat;
                                }
                            }
                            i = expressionEnd + 1;
                        }
                    }
                    else
                    {
                        result.Append(c);
                    }
                }

                return result;
            }
コード例 #12
0
            private Builder FormatObjectRecursive(Builder result, object obj, bool isRoot, out string debuggerDisplayName)
            {
                // TODO (https://github.com/dotnet/roslyn/issues/6689): remove this
                if (!isRoot && _memberDisplayFormat == MemberDisplayFormat.SeparateLines)
                {
                    _memberDisplayFormat = MemberDisplayFormat.SingleLine;
                }

                debuggerDisplayName = null;
                string primitive = _formatter.PrimitiveFormatter.FormatPrimitive(obj, _primitiveOptions);
                if (primitive != null)
                {
                    result.Append(primitive);
                    return result;
                }

                Type type = obj.GetType();
                TypeInfo typeInfo = type.GetTypeInfo();

                //
                // Override KeyValuePair<,>.ToString() to get better dictionary elements formatting:
                //
                // { { format(key), format(value) }, ... }
                // instead of
                // { [key.ToString(), value.ToString()], ... } 
                //
                // This is more general than overriding Dictionary<,> debugger proxy attribute since it applies on all
                // types that return an array of KeyValuePair in their DebuggerDisplay to display items.
                //
                if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
                {
                    if (isRoot)
                    {
                        result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions));
                        result.Append(' ');
                    }

                    FormatKeyValuePair(result, obj);
                    return result;
                }

                if (typeInfo.IsArray)
                {
                    if (VisitedObjects.Add(obj))
                    {
                        FormatArray(result, (Array)obj);

                        VisitedObjects.Remove(obj);
                    }
                    else
                    {
                        result.AppendInfiniteRecursionMarker();
                    }

                    return result;
                }

                DebuggerDisplayAttribute debuggerDisplay = GetApplicableDebuggerDisplayAttribute(typeInfo);
                if (debuggerDisplay != null)
                {
                    debuggerDisplayName = debuggerDisplay.Name;
                }

                // Suppresses members if inlineMembers is true,
                // does nothing otherwise.
                bool suppressInlineMembers = false;

                //
                // TypeName(count) for ICollection implementers
                // or
                // TypeName([[DebuggerDisplay.Value]])        // Inline
                // [[DebuggerDisplay.Value]]                  // Inline && !isRoot
                // or
                // [[ToString()]] if ToString overridden
                // or
                // TypeName 
                // 
                ICollection collection;
                if ((collection = obj as ICollection) != null)
                {
                    FormatCollectionHeader(result, collection);
                }
                else if (debuggerDisplay != null && !string.IsNullOrEmpty(debuggerDisplay.Value))
                {
                    if (isRoot)
                    {
                        result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions));
                        result.Append('(');
                    }

                    FormatWithEmbeddedExpressions(result, debuggerDisplay.Value, obj);

                    if (isRoot)
                    {
                        result.Append(')');
                    }

                    suppressInlineMembers = true;
                }
                else if (HasOverriddenToString(typeInfo))
                {
                    ObjectToString(result, obj);
                    suppressInlineMembers = true;
                }
                else
                {
                    result.Append(_formatter.TypeNameFormatter.FormatTypeName(type, _typeNameOptions));
                }

                MemberDisplayFormat memberFormat = _memberDisplayFormat;

                if (memberFormat == MemberDisplayFormat.Hidden)
                {
                    if (collection != null)
                    {
                        // NB: Collections specifically ignore MemberDisplayFormat.Hidden.
                        memberFormat = MemberDisplayFormat.SingleLine;
                    }
                    else
                    {
                        return result;
                    }
                }

                bool includeNonPublic = memberFormat == MemberDisplayFormat.SeparateLines;
                bool inlineMembers = memberFormat == MemberDisplayFormat.SingleLine;

                object proxy = GetDebuggerTypeProxy(obj);
                if (proxy != null)
                {
                    includeNonPublic = false;
                    suppressInlineMembers = false;
                }

                if (!suppressInlineMembers || !inlineMembers)
                {
                    FormatMembers(result, obj, proxy, includeNonPublic, inlineMembers);
                }

                return result;
            }
コード例 #13
0
 internal static bool IsValid(this MemberDisplayFormat value)
 {
     return(value >= MemberDisplayFormat.NoMembers && value <= MemberDisplayFormat.List);
 }
コード例 #14
0
            private Builder FormatObjectRecursive(Builder result, object obj, bool quoteStrings, MemberDisplayFormat memberFormat, out string name)
            {
                name = null;
                string primitive = _language.FormatPrimitive(obj, quoteStrings, _options.IncludeCodePoints, _options.UseHexadecimalNumbers);

                if (primitive != null)
                {
                    result.Append(primitive);
                    return(result);
                }

                object originalObj  = obj;
                Type   originalType = originalObj.GetType();

                //
                // Override KeyValuePair<,>.ToString() to get better dictionary elements formatting:
                //
                // { { format(key), format(value) }, ... }
                // instead of
                // { [key.ToString(), value.ToString()], ... }
                //
                // This is more general than overriding Dictionary<,> debugger proxy attribute since it applies on all
                // types that return an array of KeyValuePair in their DebuggerDisplay to display items.
                //
                if (originalType.IsGenericType && originalType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>))
                {
                    if (memberFormat != MemberDisplayFormat.InlineValue)
                    {
                        result.Append(_language.FormatTypeName(originalType, _options));
                        result.Append(' ');
                    }

                    FormatKeyValuePair(result, originalObj);
                    return(result);
                }

                if (originalType.IsArray)
                {
                    if (!VisitedObjects.Add(originalObj))
                    {
                        result.AppendInfiniteRecursionMarker();
                        return(result);
                    }

                    FormatArray(result, (Array)originalObj, inline: memberFormat != MemberDisplayFormat.List);

                    VisitedObjects.Remove(originalObj);
                    return(result);
                }

                DebuggerDisplayAttribute debuggerDisplay = GetApplicableDebuggerDisplayAttribute(originalType);

                if (debuggerDisplay != null)
                {
                    name = debuggerDisplay.Name;
                }

                bool suppressMembers = false;

                //
                // TypeName(count) for ICollection implementers
                // or
                // TypeName([[DebuggerDisplay.Value]])        // Inline
                // [[DebuggerDisplay.Value]]                  // InlineValue
                // or
                // [[ToString()]] if ToString overridden
                // or
                // TypeName
                //
                ICollection collection;

                if ((collection = originalObj as ICollection) != null)
                {
                    FormatCollectionHeader(result, collection);
                }
                else if (debuggerDisplay != null && !String.IsNullOrEmpty(debuggerDisplay.Value))
                {
                    if (memberFormat != MemberDisplayFormat.InlineValue)
                    {
                        result.Append(_language.FormatTypeName(originalType, _options));
                        result.Append('(');
                    }

                    FormatWithEmbeddedExpressions(result, debuggerDisplay.Value, originalObj);

                    if (memberFormat != MemberDisplayFormat.InlineValue)
                    {
                        result.Append(')');
                    }

                    suppressMembers = true;
                }
                else if (HasOverriddenToString(originalType))
                {
                    ObjectToString(result, originalObj);
                    suppressMembers = true;
                }
                else
                {
                    result.Append(_language.FormatTypeName(originalType, _options));
                }

                if (memberFormat == MemberDisplayFormat.NoMembers)
                {
                    return(result);
                }

                bool   includeNonPublic = memberFormat == MemberDisplayFormat.List;
                object proxy            = GetDebuggerTypeProxy(obj);

                if (proxy != null)
                {
                    obj = proxy;
                    includeNonPublic = false;
                    suppressMembers  = false;
                }

                if (memberFormat != MemberDisplayFormat.List && suppressMembers)
                {
                    return(result);
                }

                // TODO (tomat): we should not use recursion
                RuntimeHelpers.EnsureSufficientExecutionStack();

                result.Append(' ');

                if (!VisitedObjects.Add(originalObj))
                {
                    result.AppendInfiniteRecursionMarker();
                    return(result);
                }

                // handle special types only if a proxy isn't defined
                if (proxy == null)
                {
                    IDictionary dictionary;
                    if ((dictionary = obj as IDictionary) != null)
                    {
                        FormatDictionary(result, dictionary, inline: memberFormat != MemberDisplayFormat.List);
                        return(result);
                    }

                    IEnumerable enumerable;
                    if ((enumerable = obj as IEnumerable) != null)
                    {
                        FormatSequence(result, enumerable, inline: memberFormat != MemberDisplayFormat.List);
                        return(result);
                    }
                }

                FormatObjectMembers(result, obj, originalType, includeNonPublic, inline: memberFormat != MemberDisplayFormat.List);

                VisitedObjects.Remove(obj);

                return(result);
            }