我有以下问题:
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>'
。
我探索了一个带有通用接口但没有任何结果的解决方案......
答案 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
直接使用TabItem
时TabbedContainer
为Items
。但是,接口需要TabbedContainer.Items
作为特定接口。
诀窍是同时声明IControlCollectionContainer
和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
会返回TabbedContainer
。
请注意,这可能会变得非常复杂,具体取决于您传递/修改容器实例的方式。如果您通过IControlCollectionContainer
和List
声明不断修改项目,尝试让它们同步可能会很棘手。进行明确的实施有时可以帮助您退后一步,重新评估您的最终目标是什么,以及您在属性上声明的类型。
例如,如果您实际上没有将项目添加到界面列表中,那么为什么要使用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; }
}