使用 List<T> 属性 实现接口
Implementing interfaces with List<T> property
我有以下问题:
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!
}
此代码期望 属性 TabbedContainer.Items
中的 List<IControlSingleContainer>
但我尝试使用包含对象的 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>'
.
我探索了一个具有通用接口但没有任何结果的解决方案...
你很接近,
public class TabbedContainer : IControlCollectionContainer
{
public TabbedContainer()
{
Items = new List<IControlSingleContainer>();
var t = new TabItem();
Items.Add(t);
}
public List<IControlSingleContainer> Items { get; set; }
}
不完全确定您在这里要做什么,但您不能将 List<interface>
强制转换为 List<concrete>
。但是,您可以使您的界面通用并添加这样的约束:
public interface IControlCollectionContainer<T> where T : IControlSingleContainer
{
List<T> Items { get; set; }
}
现在你的 class 定义变成这样:
public class TabbedContainer : IControlCollectionContainer<TabItem>
{
public List<TabItem> Items { get; set; }
}
这是 explicit interface implementations 存在的原因之一,具体取决于您的用例。
在您的情况下,您希望在直接使用 TabbedContainer
时 Items
成为 TabItem
。但是,该接口要求Items
是特定接口。
诀窍是同时声明 TabbedContainer.Items
和 IControlCollectionContainer
,但在幕后重复使用 TabItem
class。
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
}
}
}
您需要更新上面的示例以实际处理 setting/getting 界面版本的项目,但主要思想是重用您的 TabItem
集合,以便它们始终保持同步。
这实际上是在您使用 TabbedContainer
并调用 Items
时,您将获得 TabItem
的列表,但是当您将实例作为 IControlCollectionContainer
,你的 Items
将 return 你 IControlCollectionContainer.Items
。
请注意,这可能会变得相当复杂,具体取决于您如何 passing/modifying 容器实例。如果您不断通过 TabbedContainer
和 IControlCollectionContainer
声明修改项目,则尝试让它们同步可能会很棘手。进行显式实现有时可以帮助您退后一步,重新准确评估您的最终目标是什么以及您在属性上声明的类型。
例如,如果您实际上并没有向界面列表中添加项目,那么为什么还要使用 List
?作为 IEnumerable<T>
或 IReadOnlyCollection<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!
}
此代码期望 属性 TabbedContainer.Items
中的 List<IControlSingleContainer>
但我尝试使用包含对象的 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>'
.
我探索了一个具有通用接口但没有任何结果的解决方案...
你很接近,
public class TabbedContainer : IControlCollectionContainer
{
public TabbedContainer()
{
Items = new List<IControlSingleContainer>();
var t = new TabItem();
Items.Add(t);
}
public List<IControlSingleContainer> Items { get; set; }
}
不完全确定您在这里要做什么,但您不能将 List<interface>
强制转换为 List<concrete>
。但是,您可以使您的界面通用并添加这样的约束:
public interface IControlCollectionContainer<T> where T : IControlSingleContainer
{
List<T> Items { get; set; }
}
现在你的 class 定义变成这样:
public class TabbedContainer : IControlCollectionContainer<TabItem>
{
public List<TabItem> Items { get; set; }
}
这是 explicit interface implementations 存在的原因之一,具体取决于您的用例。
在您的情况下,您希望在直接使用 TabbedContainer
时 Items
成为 TabItem
。但是,该接口要求Items
是特定接口。
诀窍是同时声明 TabbedContainer.Items
和 IControlCollectionContainer
,但在幕后重复使用 TabItem
class。
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
}
}
}
您需要更新上面的示例以实际处理 setting/getting 界面版本的项目,但主要思想是重用您的 TabItem
集合,以便它们始终保持同步。
这实际上是在您使用 TabbedContainer
并调用 Items
时,您将获得 TabItem
的列表,但是当您将实例作为 IControlCollectionContainer
,你的 Items
将 return 你 IControlCollectionContainer.Items
。
请注意,这可能会变得相当复杂,具体取决于您如何 passing/modifying 容器实例。如果您不断通过 TabbedContainer
和 IControlCollectionContainer
声明修改项目,则尝试让它们同步可能会很棘手。进行显式实现有时可以帮助您退后一步,重新准确评估您的最终目标是什么以及您在属性上声明的类型。
例如,如果您实际上并没有向界面列表中添加项目,那么为什么还要使用 List
?作为 IEnumerable<T>
或 IReadOnlyCollection<T>
.