2015-02-23 30 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