【发布时间】:2019-11-09 17:28:45
【问题描述】:
我正在尝试使用 dynamic 对象分离 event handler。我没有经常使用dynamic,而且我不确定我在哪里出错了。我收到的例外是:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
“object”不包含“CollectionChanged”的定义
[Fact]
public void Test()
{
var foo = new Foo();
foo.Bars = new ObservableCollection<Bar>();
foo.ClearDelegates();
}
Dictionary<string, object> _values;
Dictionary<string, NotifyCollectionChangedEventHandler> _collectionChangedDelegates;
public void ClearDelegates()
{
foreach (var kvp in _values)
{
var currentValue = _values[kvp.Key];
if (currentValue == null)
continue;
var type = currentValue.GetType();
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ObservableCollection<>))
{
dynamic observableCollection = currentValue;
observableCollection.CollectionChanged -= _collectionChangedDelegates[kvp.Key];
}
}
}
class Foo : DomainObject
{
public ObservableCollection<Bar> Bars
{
get { return GetValue<ObservableCollection<Bar>>(nameof(Bars)); }
set { SetValue(nameof(Bars), value); }
}
}
class DomainObject
{
Dictionary<string, object> _values = new Dictionary<string, object>();
Dictionary<string, NotifyCollectionChangedEventHandler> _collectionChangedDelegates =
new Dictionary<string, NotifyCollectionChangedEventHandler>();
public void ClearDelegates()
{
foreach (var kvp in _values)
{
var currentValue = _values[kvp.Key];
if (currentValue == null)
continue;
var type = currentValue.GetType();
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ObservableCollection<>))
{
dynamic observableCollection = currentValue;
observableCollection.CollectionChanged -= _collectionChangedDelegates[kvp.Key];
}
}
_collectionChangedDelegates.Clear();
}
protected T GetValue<T>(string propertyName)
{
return (T)_values[propertyName];
}
protected void SetValue<T>(string propertyName, ObservableCollection<T> value)
{
if (value != null)
HookupCollectionDelegates(propertyName, value);
Set(propertyName, value);
}
protected void SetValue<T>(string propertyName, T value)
{
Set(propertyName, value);
}
void Set<T>(string propertyName, T value)
{
_values[propertyName] = value;
OnPropertyChanged(propertyName);
}
void HookupCollectionDelegates<T>(string propertyName, ObservableCollection<T> collection)
{
var collectionChangedDelegate = delegate(object sender, NotifyCollectionChangedEventArgs e)
{
// do work
};
collection.CollectionChanged += collectionChangedDelegate;
if (_collectionChangedDelegates.ContainsKey(propertyName))
_collectionChangedDelegates[propertyName] = collectionChangedDelegate;
else
_collectionChangedDelegates.Add(propertyName, collectionChangedDelegate);
}
}
【问题讨论】:
-
您的代码运行良好。 dotnetfiddle.net。你能展示你抛出异常的用法吗?
-
@Alex 那是文字复制粘贴。我公开了该方法,并创建了一个人为的测试,编辑了主要帖子。结果相同。
Bars的设置器只是插入到值字典中。但我看到小提琴确实按预期执行......
标签: c# dynamic reflection