应该覆盖哪些方法才能正确继承“ObservableCollection”
What methods should be override to make proper inheritance of `ObservableCollection`
我想制作一个 class 来加入 Table
和 ObservableCollection
功能。所以我写道:
public sealed class ObservableTable<T> : ObservableCollection<T>, ITable<T> where T : class
{
private Table<T> _table;
public Expression Expression => _table.AsQueryable().Expression;
public Type ElementType => _table.AsQueryable().ElementType;
public IQueryProvider Provider => _table.AsQueryable().Provider;
public new IEnumerable<T> Items => _table;
public new T this[int index] => _table.ElementAt(index);
public new int Count => _table.Count();
public ObservableTable(ref DataContext dbContext)
{
_table = dbContext.GetTable<T>();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public void InsertOnSubmit(T entity)
{
_table.InsertOnSubmit(entity);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
}
public void Attach(T entity)
{
_table.Attach(entity);
}
public void DeleteOnSubmit(T entity)
{
_table.DeleteOnSubmit(entity);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove));
}
}
但是尽管 _table
对象正确地从数据库中获取了所有记录,但当我将 class 转换为 ObservableCollection
时,集合是空的。我应该重写什么才能让它工作? Items
和 Count
属性还不够吗?
因为底层ObservableCollection<T>
是空的。您将 ObservableTable<T>
的索引器和计数属性重定向到 table 中的 return 值,并且您通过 new
隐藏了原始 属性 实现,但是实际的集合,即 ObservableCollection
使用的内部存储,永远不会被填充。
如果您按原样使用 ObservableTable<T>
,一切正常。但是只要你将它转换为 ObservableCollection<T>
,索引器和计数属性的原始实现就会被调用,它们会尝试从内部存储中检索值和计数。
您没有覆盖属性,您是 "reintroducing" 在您的 class 中 隐藏了 ObservableCollection<T>
的属性。检查 the documentation or this question.
所以如果你访问 Count
属性 作为 ((ObservableCollection<T>)instanceOfObservableTable).Count
,你实际上得到了基 class 的隐藏 Count
属性 ,不是你的 "reintroduced" 属性。您只能像这样访问您的 属性:((ObservableTable<T>)instanceOfObservableTable).Count
.
Count
属性 不是虚拟的,因此您不能覆盖它。
我建议您在 class 中实现 INotifyCollectionChanged
和 INotifyPropertyChanged
接口,这样您就可以将其用作可观察集合。
我想制作一个 class 来加入 Table
和 ObservableCollection
功能。所以我写道:
public sealed class ObservableTable<T> : ObservableCollection<T>, ITable<T> where T : class
{
private Table<T> _table;
public Expression Expression => _table.AsQueryable().Expression;
public Type ElementType => _table.AsQueryable().ElementType;
public IQueryProvider Provider => _table.AsQueryable().Provider;
public new IEnumerable<T> Items => _table;
public new T this[int index] => _table.ElementAt(index);
public new int Count => _table.Count();
public ObservableTable(ref DataContext dbContext)
{
_table = dbContext.GetTable<T>();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public void InsertOnSubmit(T entity)
{
_table.InsertOnSubmit(entity);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
}
public void Attach(T entity)
{
_table.Attach(entity);
}
public void DeleteOnSubmit(T entity)
{
_table.DeleteOnSubmit(entity);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove));
}
}
但是尽管 _table
对象正确地从数据库中获取了所有记录,但当我将 class 转换为 ObservableCollection
时,集合是空的。我应该重写什么才能让它工作? Items
和 Count
属性还不够吗?
因为底层ObservableCollection<T>
是空的。您将 ObservableTable<T>
的索引器和计数属性重定向到 table 中的 return 值,并且您通过 new
隐藏了原始 属性 实现,但是实际的集合,即 ObservableCollection
使用的内部存储,永远不会被填充。
如果您按原样使用 ObservableTable<T>
,一切正常。但是只要你将它转换为 ObservableCollection<T>
,索引器和计数属性的原始实现就会被调用,它们会尝试从内部存储中检索值和计数。
您没有覆盖属性,您是 "reintroducing" 在您的 class 中 隐藏了 ObservableCollection<T>
的属性。检查 the documentation or this question.
所以如果你访问 Count
属性 作为 ((ObservableCollection<T>)instanceOfObservableTable).Count
,你实际上得到了基 class 的隐藏 Count
属性 ,不是你的 "reintroduced" 属性。您只能像这样访问您的 属性:((ObservableTable<T>)instanceOfObservableTable).Count
.
Count
属性 不是虚拟的,因此您不能覆盖它。
我建议您在 class 中实现 INotifyCollectionChanged
和 INotifyPropertyChanged
接口,这样您就可以将其用作可观察集合。