存储在集合中实现通用接口的对象

时间:2013-06-21 12:55:13

标签: c# .net

我有许多类都在实现IWidget<T>接口。我想将它们添加到列表中,所以我定义了这样的内容:

List<IWidget<T>> _widgetList; 

这里编译器抱怨T未被识别:

  

错误1找不到类型或命名空间名称“T”(您是否缺少using指令或程序集引用?)

有没有办法定义IWidget列表并仍保留通用接口?

我使用的是.NET 3.5 SP1。

3 个答案:

答案 0 :(得分:5)

有几种方法可以做到这一点:

1)您需要一个非通用的根目录:

public interface IWidget
{
      ...
}

public interface IWidget<T> : IWidget
{
      ...
}

以便您可以使用List<IWidget> _widgetList;


2)你可以使用dynamic或多态与对抗/协方差,但你必须遵守规则, {{1 }}必须不是值类型,您必须在访问后进行强制转换,但不能在添加时进行强制转换,如下所示:

<T>

3)或者您可以混合使用这两种方法:

IWidget<string> xxx = ...;

var widgetListDyn = new List<IWidget<dynamic>>();
var widgetListObj = new List<IWidget<object>>();

widgetListDyn.Add(xxx);
widgetListObj.Add(xxx);

你可以使用public interface IWidget : IWidget<object> {} 这种技巧,你也需要在List<IWidget> _widgetList;之前进行演员:

.add()

4)最后一种方法是:

List<IWidget> _widgetList = new List<IWidget>();
IWidget<string> xxx = ...;
IWidget xxx1 = (IWidget)xxx;

_widgetList.Add(xxx1);

如果您计划声明创建了大量列表,那将非常有用,这样可以避免使用:public class IWidgetList<T> : List<IWidget<T>> { } 的丑陋语法,而只需使用:List<IWidget<TYPE>>并且它是相同的

答案 1 :(得分:2)

您需要使用非通用的根接口:

public interface IWidget<T> : IWidget
{
}

或在声明点指定类型:

List<IWidget<MyType>> widgetList;

答案 2 :(得分:2)

你的IWidget接口是通用的吗,即它实际上是IWidget&lt; T&gt;?或者只是IWidget?

如果它不是通用界面,您只需要以下内容:

public class ContainingClass
{
   List<IWidget> _widgetList;
}

如果它是通用接口,那么你需要的是这样的:

public class ContainingClass<T> where T : class // or some other constraint for T
{
   List<IWidget<T>> _widgetList;
}