我有许多类都在实现IWidget<T>
接口。我想将它们添加到列表中,所以我定义了这样的内容:
List<IWidget<T>> _widgetList;
这里编译器抱怨T未被识别:
错误1找不到类型或命名空间名称“T”(您是否缺少using指令或程序集引用?)
有没有办法定义IWidget列表并仍保留通用接口?
我使用的是.NET 3.5 SP1。
答案 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;
}