【发布时间】:2022-11-10 03:34:10
【问题描述】:
请考虑以下代码:
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;
}
}
它实现了一个字典,其键可以像属性一样被访问:
dynamic Vars = new DynamicDictionary();
Vars.Test = "Something happened";
它工作正常,除了调试器动态视图节点在展开时显示错误消息“无法评估表达式。不支持操作。未知错误:0x80070057”:
扩展结果视图当然可以按预期工作。
现在我知道错误代码0x80070057 是E_INVALIDARG,但这并不能真正帮助解释这里发生的事情。根据我在debugger expression documentation 中找到的内容,它应该可以工作:
在 Watch 窗口中评估实现
System.Dynamic.IDynamicMetaObjectProvider的对象时,会添加一个动态视图节点。动态视图节点显示对象成员,但不允许编辑成员的值。如果我从
InnerObject中删除[DebuggerBrowsable(DebuggerBrowsableState.Never)],它自己的动态视图节点可以展开以显示值而不会出错。所以问题是——我是否遗漏了一些覆盖
InnerObject的覆盖,以便调试器的动态视图节点在DynamicDictionary类实例上工作,如果是这样,是哪一个,或者由于某些调试器限制而根本不可能?我也愿意接受更好的问题标题的建议。
【问题讨论】: