请考虑以下代码:
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";
它运行正常,但调试器动态视图节点除外,该节点在展开时显示错误消息“无法计算表达式。不支持操作。未知错误:0x 80070057”的名称:
当然,展开“结果视图”会按预期工作。
现在我知道错误代码0x80070057
是E_INVALIDARG
,但它并不能真正解释这里发生了什么。根据我在调试器表达式文档中找到的内容,它应该可以工作:
在[监看式]视窗中评估实作System.Dynamic.IDynamicMetaObjectProvider
的对象时,会加入[动态检视]节点。[动态检视]节点会显示对象成员,但不允许编辑成员的值。
如果我从InnerObject
中删除[DebuggerBrowsable(DebuggerBrowsableState.Never)]
,它自己的“动态视图”节点可以展开以显示值,而不会出现错误。
因此,问题是--我是否遗漏了一些覆盖,这些覆盖将在这里 Package InnerObject
,以便调试器的Dynamic View节点在DynamicDictionary
类示例上工作,如果是,是哪一个,或者由于某些调试器限制而根本不可能做到这一点?
我也愿意接受关于更好的问题标题的建议。
1条答案
按热度按时间wz1wpwve1#
它相信如果你重写GetDynamicMemberNames,这是让“动态视图”工作的一个步骤。我还没有尝试过继承DynamicObject。相反,我在实现IDynamicMetaObjectProvider时遇到了这个问题。而且,对我来说,如果在阅读任何属性值时使用的任何内部逻辑出错,或者调用Debugger.NotifyOfCrossThreadDependency,这也可以阻止它显示任何值。