2014-02-18 55 views
2

是否可以將接口指定爲不同接口的通用集合屬性的類型,然後使用特定類實現它?這裏是什麼,我試圖做一個例子:ICollection與另一個接口的接口類型爲

public interface IMembershipPrincipal 
{ 
    int ID { get; set; } 
    string UserName { get; set; } 
    ICollection<IEmail> Emails { get; set; } 
} 

public interface IEmail 
{ 
    string Address { get; set; } 
    int UserID { get; set; } 
} 

,並確定在另一個項目的實際類:

public class User : IMembershipPrincipal 
{ 
    [Key] 
    public int ID { get; set; } 
    public string UserName { get; set; } 
    public virtual ICollection<Email> Emails { get; set; } 
} 

public class Email : IEmail 
{ 
    [Key] 
    public string Address { get; set; } 
    public int UserID { get; set; } 
} 

在IMembershipPrincipal我只能訪問到IEmail定義,但我會喜歡使用電子郵件而不是IEmail實現ICollection。我目前收到一條錯誤消息:

錯誤1'用戶'未實現接口成員'IMembershipPrincipal.Emails'。 「User.Emails」無法實現「IMembershipPrincipal.Emails」,因爲它沒有System.Collections.Generic.ICollection'.`

的」匹配的返回類型我怎樣才能改變我的IMembershipPrincipal定義,使其能用ICollection<Email>實施?

爲了清楚起見,我知道將虛擬集合實現爲ICollection<IEmail>將使代碼生成,但它會破壞我在Entity框架中的路徑,因此我不能執行類似MyUser.Emails.Where(...)的操作。

+0

你不能。 'ICollection '不是協變的,所以您不能將'Email'實例添加到'ICollection '。這是設計。 – MarcinJuraszek

+0

我可以使用協變的ICollection以外的東西嗎? – Dusty

+1

不可以。沒有辦法獲得允許「添加」操作的協變集合。 – MarcinJuraszek

回答

2

正如其他人所提到的,協方差使您無法使用示例中的代碼。但是,您可以使用泛型類型和約束來獲得所需的效果。

public interface IMembershipPrincipal<T> where T:IEmail 
{ 
    int ID { get; set; } 
    string UserName { get; set; } 
    ICollection<T> Emails { get; set; } 
} 

public interface IEmail 
{ 
    string Address { get; set; } 
    int UserID { get; set; } 
} 

public class User : IMembershipPrincipal<Email> 
{ 
    [Key] 
    public int ID { get; set; } 
    public string UserName { get; set; } 
    public virtual ICollection<Email> Emails { get; set; } 
} 

public class Email : IEmail 
{ 
    [Key] 
    public string Address { get; set; } 
    public int UserID { get; set; } 
} 
+0

像魅力一樣工作。泛型類型正是我所需要的。謝謝! – Dusty