2013-02-13 87 views
2

我有一個廣泛實現的接口,有一個IList與一個特定的接口。 而是大量文字的,看看這裏:IList <InterfaceType>爲List <ImplementsInterfaceType>?

interface ILanguage 
{ 
    IList<ITriggers> CompletionTriggers { get; set; } 
} 

public class Language : ILanguage 
{ 
    public Constructor() 
    { 
     CompletionTriggers = new List<CompletionTrigger>(); 
    } 
} 

這基本上就是我想要做的事。 「觸發器」是一個接口的成員,它由幾種類型實現。但每種類型都需要一個自定義的ITrigger實現和列表(我使用IList,因爲它看起來相當方便)。

錯誤顯示「Missing a cast?」,但我覺得很奇怪,因爲這兩個對象都是直接實現IList和ITrigger(List和CompletionTrigger)。

我認爲這是一件容易的事情,但爲什麼它表現得像這樣的一些點非常感謝!

+0

你靶向什麼版本的.NET? – 2013-02-13 00:59:37

+0

4客戶資料 – 2013-02-13 01:00:12

+0

您是否在考慮[協方差](http://stackoverflow.com/q/245607/11683)? – GSerg 2013-02-13 01:08:27

回答

5

我想,這是一件容易的事情

這並不容易。至少不是容易。這是不允許的原因最好用一個例子來解釋。假設它被允許像你建議做任務:

// Let's make another trigger unrelated to CompletionTrigger 
class ContinuationTrigger : ITrigger { 
} 
// This is allowed 
List<CompletionTrigger> myTriggers = new List<CompletionTrigger>(); 
// THIS WILL NOT WORK (but let's pretend that it does) 
IList<ITriggers> CompletionTriggers = myTriggers; 
// Here comes trouble: 
CompletionTriggers.Add(new ContinuationTrigger()); 

由於CompletionTriggersIList<ITriggers>型和ContinuationTriggerITrigger,編譯器必須允許Add電話。但是,這會將延續觸發器放入myTriggers,該集合已被創建爲List<CompletionTrigger>,這絕對是不允許的。

就克服這一點而言,您有幾種選擇。最簡單的方法是同等對待對象,僅在對象創建時區分對象。這可能會很棘手,並且在某些情況下需要多次調度。

另一種選擇是獲取和設置的CompletionTriggers元素使得通用蓋:

void SetCompletionTriggers<T>(IList<T> triggers) where T : ITrigger { 
    CompletionTriggers = triggers.Cast<ITrigger>().ToList(); 
} 
IEnumerable<T> GetCompletionTriggers<T>() where T : ITrigger { 
    return CompletionTriggers.Cast<T>(); 
} 
+0

優秀的答案!現在我很明白髮生了什麼事情。現在我將「CompletionTriggers」初始化爲「新列表()」,然後在後面添加「自定義」觸發器(即直接執行ITrigger)。 謝謝! – 2013-02-13 01:25:17

0

我認爲,如果你要定義列表爲IList<ITriggers>那麼當你新的它,它必須是new List<ITriggers>

如果你真的想創建一個特定類型的列表,你可以讓你的界面通用

interface ITriggers 
{ 
} 

class CompletionTrigger : ITriggers 
{ 
} 

interface ILanguage<T> where T: ITriggers 
{ 
    List<T> CompletionTriggers { get; set; } 
} 

class Language : ILanguage<CompletionTrigger> 
{ 
    public List<CompletionTrigger> CompletionTriggers { get; set; } 
    public Language() 
    { 
     CompletionTriggers = new List<CompletionTrigger>(); 
    } 
} 
相關問題