Я пытаюсь отсоединить 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);
}
}