Is it possible to get C# debugger Dynamic View node to work for this class?

Viewed 22

Please consider this code:

    public class DynamicDictionary : DynamicObject, IDictionary<string, object?>
    {
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private ExpandoObject InnerObject = new ExpandoObject();

        public object? this[string key] {
            get {
                return ((IDictionary<string, object?>)InnerObject)[key];
            }

            set {
                ((IDictionary<string, object?>)InnerObject)[key] = value;
            }
        }

        public ICollection<string> Keys {
            get {
                return ((IDictionary<string, object?>)InnerObject).Keys;
            }
        }

        public ICollection<object?> Values {
            get {
                return ((IDictionary<string, object?>)InnerObject).Values;
            }
        }

        public int Count {
            get {
                return ((ICollection<KeyValuePair<string, object?>>)InnerObject).Count;
            }
        }

        public bool IsReadOnly {
            get {
                return ((ICollection<KeyValuePair<string, object?>>)InnerObject).IsReadOnly;
            }
        }

        public void Add(string key, object? value)
        {
            ((IDictionary<string, object?>)InnerObject).Add(key, value);
        }

        public void Add(KeyValuePair<string, object?> item)
        {
            ((ICollection<KeyValuePair<string, object?>>)InnerObject).Add(item);
        }

        public void Clear()
        {
            ((ICollection<KeyValuePair<string, object?>>)InnerObject).Clear();
        }

        public bool Contains(KeyValuePair<string, object?> item)
        {
            return ((ICollection<KeyValuePair<string, object?>>)InnerObject).Contains(item);
        }

        public bool ContainsKey(string key)
        {
            return ((IDictionary<string, object?>)InnerObject).ContainsKey(key);
        }

        public void CopyTo(KeyValuePair<string, object?>[] array, Int32 arrayIndex)
        {
            ((ICollection<KeyValuePair<string, object?>>)InnerObject).CopyTo(array, arrayIndex);
        }

        public IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
        {
            return ((IEnumerable<KeyValuePair<string, object?>>)InnerObject).GetEnumerator();
        }

        public bool Remove(string key)
        {
            return ((IDictionary<string, object?>)InnerObject).Remove(key);
        }

        public bool Remove(KeyValuePair<string, object?> item)
        {
            return ((ICollection<KeyValuePair<string, object?>>)InnerObject).Remove(item);
        }

        public bool TryGetValue(string key, [MaybeNullWhen(false)] out object? value)
        {
            return ((IDictionary<string, object?>)InnerObject).TryGetValue(key, out value);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable)InnerObject).GetEnumerator();
        }

        public override bool TryGetMember(GetMemberBinder binder, out object? result)
        {
            return ((IDictionary<string, object?>)InnerObject).TryGetValue(binder.Name, out result);
        }

        public override bool TrySetMember(SetMemberBinder binder, object? value)
        {
            ((IDictionary<string, object?>)InnerObject)[binder.Name] = value;
            return true;
        }
    }

It implements a dictionary whose keys can be accessed like properties:

    dynamic Vars = new DynamicDictionary();
    Vars.Test = "Something happened";

It works ok, except for the debugger Dynamic View node which when expanded shows an error message "Unable to evaluate the expression. Operation not supported. Unknown error: 0x80070057": Debugger view

Expanding Results View of course works as expected.

Now I know that error code 0x80070057 is E_INVALIDARG, but it doesn't really help explain what is happening here. From what I have found in the debugger expression documentation it should work:

When objects that implement System.Dynamic.IDynamicMetaObjectProvider are evaluated in the Watch window, a Dynamic View node is added. The Dynamic View node shows object members but does not allow editing the values of the members.

If I remove [DebuggerBrowsable(DebuggerBrowsableState.Never)] from InnerObject its own Dynamic View node can be expanded to show values without error.

So the question is -- am I missing some override that would wrap InnerObject here for the debugger's Dynamic View node to work on the DynamicDictionary class instance and if so which one, or is that simply not possible due to some debugger limitation?

I am also open to suggestions for a better question title.

0 Answers
Related