2015-02-23 27 views
0

實現接口我有以下問題:與列表<T>財產

public interface IControlSingleContainer 
{ 
    ControlCollection Content { get; set; } 
} 

public interface IControlCollectionContainer 
{ 
    // I need to obtain a List of objects that implement IControlSingleContainer interface 
    List<IControlSingleContainer> Items { get; set; } 
} 

public class TabItem : IControlSingleContainer 
{ 
    public ControlCollection Content { get; set; } 
} 

public class TabbedContainer : IControlCollectionContainer 
{ 
    public List<TabItem> Items { get; set; } <- ERROR! 
} 

這段代碼期望List<IControlSingleContainer>在房地產TabbedContainer.Items但我儘量用包含實現IControlSingleContainer對象Items屬性創建類。

編輯:基本上,編譯錯誤如下: 'Cosmo.UI.Controls.TabbedContainer' does not implement interface member 'Cosmo.UI.Controls.IControlCollectionContainer.Items'. 'Cosmo.UI.Controls.TabbedContainer.Items' can not implement' Cosmo.UI.Controls.IControlCollectionContainer.Items' because it has the kind of matching return value of 'System.Collections.Generic.List <Cosmo.UI.Controls. IControlSingleContainer>'

我探索與通用接口,但沒有任何結果的解決方案...

+1

如果你遇到一個錯誤,並且你發佈了這個問題尋找幫助修復這個錯誤....但是甚至沒有打擾說錯誤實際上是什麼,那麼你失敗了。 – 2015-02-23 23:54:09

+1

有什麼錯誤消息?我打賭這是一個對象引用錯誤,因爲你沒有實例化列表。嘗試在類的構造函數中實例化列表 – 2015-02-23 23:55:36

+0

嗨JK,我的英語不是最好的......對不起!我試着更好地解釋這個錯誤:當你編譯代碼時,我在TabbedContainer類的Items屬性中得到一個錯誤,因爲它期望列表List 。我真的希望這個列表適用於實現接口IControlSingleContainer的類。我無法找到如何得到這個。我希望這是清楚我的問題...... :) – 2015-02-24 00:02:22

回答

2

不能完全確定你正在嘗試做的,但你不能強迫將List<interface>轉換爲List<concrete>。但是,你可以讓你的接口通用,並添加這樣的約束:

public interface IControlCollectionContainer<T> where T : IControlSingleContainer 
{ 
    List<T> Items { get; set; } 
} 

現在你的類定義變成這樣:

public class TabbedContainer : IControlCollectionContainer<TabItem> 
{ 
    public List<TabItem> Items { get; set; } 
} 
+0

感謝DavidG,這正是我一直在尋找的解決方案!謝謝大家! :) – 2015-02-24 00:28:55

0

你靠近,

public class TabbedContainer : IControlCollectionContainer 
    { 
     public TabbedContainer() 
     { 
      Items = new List<IControlSingleContainer>(); 
      var t = new TabItem(); 
      Items.Add(t); 
     } 

     public List<IControlSingleContainer> Items { get; set; } 
    } 
+0

這個解決方案已經評估過(並且肯定工作正常),但是沒有辦法爲特定對象類型(實現接口IControlSingleContainer)創建Items屬性? – 2015-02-24 00:25:21

1

這是存在取決於你的使用情況explicit interface implementations的原因之一。

在你的情況下,你希望你的Items直接使用TabbedContainer時爲TabItem。但是,該接口要求Items是一個特定的接口。

訣竅是同時宣佈TabbedContainer.ItemsIControlCollectionContainer,但在幕後重用您的TabItem類。

public class TabbedContainer : IControlCollectionContainer 
{ 
    public List<TabItem> Items { get; set; } 

    List<IControlSingleContainer> IControlCollectionContainer.Items 
    { 
     get 
     { 
      return // Your actual tab items 
     } 

     set 
     { 
      Items = //Whatever you need to do make sure you have actual 
        // TabItem objects 
     } 
    } 
} 

你需要更新上述實際處理設置/獲取的項目接口的版本的樣品,但其主要思想是,使他們始終保持同步重用你TabItem集合。

什麼這實際上做的是當你與TabbedContainer工作,並呼籲Items,你會得到的TabItem列表,但您的實例工作作爲IControlCollectionContainer時,你Items將返回的IControlCollectionContainer.Items代替。

請注意,根據您傳遞/修改容器實例的方式,這可能會變得相當複雜。如果您不斷修改通過TabbedContainerIControlCollectionContainer聲明的項目,試着讓它們同步可能會非常棘手。做顯式實現有時可以幫助您退後一步,準確地重新評估您的最終目標是什麼以及您在屬性上聲明瞭哪些類型。例如,如果您實際上沒有將項目添加到您的界面列表中,那爲什麼還要使用List?作爲IEnumerable<T>IReadOnlyCollection<T>可能會更好。

+0

謝謝TyCobb ...明天我會探索這個解決方案...現在這裏是凌晨1點,我非常累! :) 謝謝! – 2015-02-24 00:35:57

+0

@GerardLlort沒問題。這只是另一種選擇。總有一百萬種方法可以做事,這個取決於你的用例。祝你好運。 – TyCobb 2015-02-24 00:43:37