使用List <t>属性</t>实现接口

时间:2015-02-23 23:51:26

标签: c# interface

我有以下问题:

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,但我尝试创建包含Items属性的类,其中包含实现IControlSingleContainer的对象。

编辑:基本上,编译错误如下: '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>'

我探索了一个带有通用接口但没有任何结果的解决方案......

3 个答案:

答案 0 :(得分: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; } 
}

答案 1 :(得分:1)

这是explicit interface implementations存在的原因之一,具体取决于您的用例。

在您的情况下,您希望Items直接使用TabItemTabbedContainerItems。但是,接口需要TabbedContainer.Items作为特定接口。

诀窍是同时声明IControlCollectionContainerTabItem,但在幕后重复使用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会返回TabbedContainer

请注意,这可能会变得非常复杂,具体取决于您传递/修改容器实例的方式。如果您通过IControlCollectionContainerList声明不断修改项目,尝试让它们同步可能会很棘手。进行明确的实施有时可以帮助您退后一步,重新评估您的最终目标是什么,以及您在属性上声明的类型。

例如,如果您实际上没有将项目添加到界面列表中,那么为什么要使用IEnumerable<T>?它可以更好地作为IReadOnlyCollection<T>或{{1}}。

答案 2 :(得分:0)

你很亲密,

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

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