在集合中存储实现泛型接口的对象
本文关键字:泛型接口 对象 实现 存储 集合 | 更新日期: 2023-09-27 18:19:18
我有许多类都实现了IWidget<T>
接口。我想把它们添加到一个列表中,所以我定义如下:
List<IWidget<T>> _widgetList;
这里编译器抱怨T没有被识别:
错误1无法找到类型或命名空间名称'T'(您是否缺少using指令或程序集引用?)
是否有一种方法来定义IWidget列表,仍然保持通用接口?
我正在使用。net 3.5 SP1。
有几种方法可以做到这一点:
1)你需要一个非通用的根:
public interface IWidget
{
...
}
public interface IWidget<T> : IWidget
{
...
}
这样你就可以使用List<IWidget> _widgetList;
2)您可以使用dynamic
s或多态性与contra/协方差,但您必须按照规则来玩, <T>
不能是值类型,您必须在访问后强制转换,但不是在添加时,像这样:
IWidget<string> xxx = ...;
var widgetListDyn = new List<IWidget<dynamic>>();
var widgetListObj = new List<IWidget<object>>();
widgetListDyn.Add(xxx);
widgetListObj.Add(xxx);
3)或者您可以混合使用这两种方法:
public interface IWidget : IWidget<object> {}
,你可以用这个技术使用List<IWidget> _widgetList;
,你也需要在.add()
:
List<IWidget> _widgetList = new List<IWidget>();
IWidget<string> xxx = ...;
IWidget xxx1 = (IWidget)xxx;
_widgetList.Add(xxx1);
4)最后一种方法是:
public class IWidgetList<T> : List<IWidget<T>> { }
,这将是有用的,如果你计划有一个声明,在创建了很多列表,让你从丑陋的语法:List<IWidget<TYPE>>
,而不是你可以使用:IWidgetList<TYPE>
,它是相同的
您的IWidget接口是通用的吗,即它实际上是IWidget
如果它不是一个通用的接口,你只需要如下:
public class ContainingClass
{
List<IWidget> _widgetList;
}
如果它是一个泛型接口,那么你需要的是这样的东西:
public class ContainingClass<T> where T : class // or some other constraint for T
{
List<IWidget<T>> _widgetList;
}
你需要使用一个非通用的根接口:
public interface IWidget<T> : IWidget
{
}
或者在声明点指定类型:
List<IWidget<MyType>> widgetList;