我正在尝试使用event handler
对象分离dynamic
。我使用dynamic
的次数很少,而且不确定在哪里出错。我收到的异常是:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
“对象”不包含“ 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);
}
}
答案 0 :(得分:3)
我也喜欢新功能,但我们不应该忘记旧功能。您的字典看起来像一个关系。我想现在是LINQ
时间,请帮助我们Dictionary<string, object> _values;
Dictionary<string, NotifyCollectionChangedEventHandler> _collectionChangedDelegates;
void ClearDelegates()
{
foreach (var i in
_values.Join(_collectionChangedDelegates,
outer => outer.Key,
inner => inner.Key,
(outer, inner) =>
new
{
Target = (INotifyCollectionChanged)outer.Value,
EventHandler = inner.Value
})) // expected, you manage your dictionaries carefully
i.Target.CollectionChanged -= i.EventHandler;
_collectionChangedDelegates.Clear();
}
。
app_lang
答案 1 :(得分:2)
要避免受run-time
dynamic
约束的问题,请保持强键入。介意CollectionChanged
事件是在INotifyCollectionChanged
中定义的,而不是在ObservableCollection<T>
中定义的,因此您实际上不需要需要dynamic
。这段代码有助于避免出现问题,位于compile-time
。
Dictionary<string, object> _values;
Dictionary<string, NotifyCollectionChangedEventHandler> _collectionChangedDelegates;
void ClearDelegates()
{
foreach(var key in _values.Keys)
if (_values[key] is INotifyCollectionChanged value &&
_collectionChangedDelegates.TryGetValue(key, out var handler))
value.CollectionChanged -= handler;
_collectionChangedDelegates.Clear();
}