在集合中存储实现泛型接口的对象

本文关键字:泛型接口 对象 实现 存储 集合 | 更新日期: 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?或者仅仅是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;