3

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

List<IWidget<T>> _widgetList; 

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

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

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

我正在使用 .NET 3.5 SP1。

4

3 回答 3

5

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

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

public interface IWidget
{
      ...
}

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

这样你就可以使用List<IWidget> _widgetList;


2)您可以使用dynamics 或带反/协变的多态性,但您必须遵守它所具有的规则,<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;这种技术,您还需要在 a 之前进行演员表.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>它是相同的

于 2013-06-21T13:01:33.330 回答
2

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

public interface IWidget<T> : IWidget
{
}

或在声明时指定类型:

List<IWidget<MyType>> widgetList;
于 2013-06-21T12:57:33.707 回答
2

您的 IWidget 接口是通用的,即它实际上是 IWidget<T> 吗?还是只是 IWidget?

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

public class ContainingClass
{
   List<IWidget> _widgetList;
}

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

public class ContainingClass<T> where T : class // or some other constraint for T
{
   List<IWidget<T>> _widgetList;
}
于 2013-06-21T13:03:07.377 回答