我希望我的对象能够引用他们所居住的集合。
我有一个派生类派生自ObservableCollection<>
:
public class MyObservableCollection<T> : ObservableCollection<T> where T: class, IMyItem
public interface IMyItem
{
MyObservableCollection<IMyItem> Owner;
}
在其中,我已覆盖Insert( )
和Remove( )
,以便它可以将自己分配给IMyItem
上的属性,但我不允许因为
Cannot implicitly convert type 'MyObservableCollection<T>' to
'MyObservableCollection<IMyItem>'
如何解决这个问题?
可以/应该以完全不同的方式解决问题吗?
插入代码:
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
item.Owner = this;
}
答案 0 :(得分:1)
如果您定义了这样的界面,它应该可以工作:
public interface IMyItem<T> where T : class, IMyItem<T>
{
MyObservableCollection<T> Owner { get; set; }
}
public class MyItem : IMyItem<MyItem>
{
public MyObservableCollection<MyItem> Owner { get; set; }
}
public class MyObservableCollection<T> : ObservableCollection<T> where T : class, IMyItem<T>
{
protected override void InsertItem ( int index, T item )
{
base.InsertItem ( index, item );
item.Owner = this;
}
}
用法:
public class MyClass
{
public static void Main ()
{
MyObservableCollection<MyItem> list = new MyObservableCollection<MyItem> ();
list.Add ( new MyItem () );
}
}
答案 1 :(得分:0)
假设您有实现接口的Item类:
class Item : IMyItem
{
public MyObservableCollection<IMyItem> Owner;
}
现在,您正在创建一个新集合:
var myCollection = new MyObservableCollection<Item>();
myCollection.Insert(new Item());
现在,在您的Insert()
方法中,您正在执行此任务:
newItem.Owner = this;
但您的newItem.Owner
类型为MyObservableCollection<IMyItem>
,而this
属于更具体的类型MyObservableCollection<Item>
。你遇到的是通用covariance/contravariance的问题。 Item
可能会继承IMyItem
,但List<Item>
不会继承List<IMyItem>
。
Stephan Bauer的回答为您提供了一种解决方法,让IMyItem
接口具有对自身的通用引用,从而跳过整个协方差问题。另一个想法是使用IEnumerable<T>
而不是ObservableCollection<T>
,因为IEnumerable
被定义为<out T>
,这意味着它支持继承期间的协方差。