2012-09-03 100 views
0

我希望我的對象必須是他們生活在集合的引用分配泛型類型物業

我有一個集合類從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; 
    } 
+1

你已經在'IMyItem'上設置了一個類型約束,但是錯誤信息提到了'IMoveableItem'。寫這個問題只是一個錯誤嗎? –

+0

是的,一個錯字。對不起... – Vegar

回答

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()); 
    } 
} 
+0

我無法用這種方式聲明具體類: public class MyItem:IMyItem public MyObservableCollection Owner {get; set;} end; 這是告訴我,MyItem必須傳達IMyItem 爲了使用它作爲泛型類MyObservableCollection中的參數'T'' – Vegar

+0

我更新了我的答案,一個完整的例子,適用於我... –

+0

你是對,我忘了在MyObservableCollection的where約束上添加一個。所以它的工作原理,但我真正的代碼是更復雜一點,涉及MyItem的多個子類。當我需要引用任何類型的IMyItem <>時,我無法這樣做,因爲IMyItem上的類型參數... – Vegar

0

比方說,你有項目類實現您的界面:

class Item : IMyItem 
{ 
    public MyObservableCollection<IMyItem> Owner; 
} 

現在,你要創建一個新的集合:

var myCollection = new MyObservableCollection<Item>(); 
myCollection.Insert(new Item()); 

現在,在Insert()方法,你在做這個任務:

newItem.Owner = this; 

但你newItem.OwnerMyObservableCollection<IMyItem>型而this是更具體類型MyObservableCollection<Item>。您遇到的問題是通用covariance/contravariance的問題。 Item可能從IMyItem繼承,但List<Item>不會從List<IMyItem>繼承。

Stephan Bauer的回答爲您提供瞭解決方法,讓IMyItem接口具有對自身的通用引用,從而跳過了整個協方差問題。不同的想法是使用IEnumerable<T>而不是ObservableCollection<T>,因爲IEnumerable被定義爲<out T>,這意味着它支持繼承期間的協方差。

+0

但我需要引用該集合的原因之一是我需要操縱它,而我不能通過IEnumerable來完成。 – Vegar

+0

在這種情況下,斯蒂芬鮑爾的答案可能是適合你的。 –