我有许多类都实现了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 或带反/协变的多态性,但您必须遵守它所具有的规则,<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>
它是相同的
您需要使用非通用根接口:
public interface IWidget<T> : IWidget
{
}
或在声明时指定类型:
List<IWidget<MyType>> widgetList;
您的 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;
}