private static void PrintEachItemInList<T>(T anyList)
Where T:System.Collections.Generic.List<T>
{
foreach (var t in T)
{
//Do whatever
}
}
在上面的代码中(这是错误的)我只想设置一个T
是List的约束。
目的不是让这个例子起作用,目的是要了解如何设置类型为列表的约束?我是仿制药的业余爱好者,我正在努力解决问题:(
答案 0 :(得分:6)
将输入参数声明为IList<T>
。如果您想使输入序列尽可能抽象 - 请使用IEnumerable<T>
代替IList<T>
private static void PrintEachItemInList<T>(IList<T> sequence)
{
foreach (T element in sequence)
{
//Do whatever
}
}
答案 1 :(得分:5)
也许你想要两个类型参数,如:
private static void PrintEachItemInList<TList, TItem>(TList anyType)
where TList : System.Collections.Generic.List<TItem>
如果您使用实际派生自List<>
的类,这将非常有用。如果您想要行为作为列表的任何内容,请考虑改为约束接口 IList<>
。然后它将适用于List<>
,单维数组和实现接口的自定义类(但不一定来自List<>
)。
编辑:正如评论所指出的,这种方法使用起来很麻烦,因为编译器不会推断出两种类型的参数,因此在调用方法时必须明确给出它们。 / p>
考虑使用:
private static void PrintEachItemInList<TItem>(List<TItem> anyType)
因为从List<>
派生的任何内容都可以赋值给List<>
,所以可以使用派生类作为参数调用该方法,并且在许多情况下,类型TItem
可以通过自动推断编译器。
仍然考虑使用界面IList<>
。
如果你想要做的只是从列表中读取,请使用IReadOnlyList<TItem>
代替IList<TItem>
。这向呼叫者发出信号,表示您不会更改其列表。调用时仍然不需要强制转换语法,例如:PrintEachItemInList(new[] { 2, 3, 5, 7, });
。类型IReadOnlyList<>
是.NET 4.5版中的新增功能。
如果要从列表中读取所有操作,并且您不想使用索引器(无anyType[idx]
),并且您不想使用.Count
属性,事实上,你想要做的就是通过列表foreach
,使用IEnumerable<TItem>
。再一次,你发出信号表明你不会改变人们的名单。
IReadOnlyList<>
和IEnumerable<>
在其通用参数(类型参数)中都是协变。
答案 2 :(得分:3)
您的函数应该只接受一个列表,而您不需要约束:
private static void PrintEachItemInList<T>(IList<T> list)
{
foreach (var t in list)
{
//Do whatever
}
}
但是,如果您只想迭代列表,可以通过将参数类型更改为其中一个基本接口来使代码更通用:
IEnumerable<T>
- 允许foreach
IReadOnlyCollection
- 与上述相同,并提供集合中元素的数量IReadOnlyList
- 与上述相同,并允许按索引进行元素访问ICollection<T>
- 提供元素计数的IEnumerable<T>
以及添加和删除元素的方法IList<T>
- 与上述相同,允许您按索引添加和删除元素答案 3 :(得分:2)
如果你想使用参数多态来表达那个约束,在c#中你需要两个类型参数(因为你没有得到更高阶的类型):
private static void PrintEachItemInList<X, T>(X anyType) where X:System.Collections.Generic.List<T>
{
foreach (var t in anyType)
{
Console.WriteLine(t.ToString());
}
}
然后你需要像这样打电话:
PrintEachItemInList<List<string>,string>(new List<string>() {"a", "b"});
答案 4 :(得分:1)
您通常会将其写为:
private static void PrintEachItemInList<T>(List<T> anyType)
{
// do work
}
但是,在这种情况下,我建议改为使用IEnumerable<T>
:
private static void PrintEachItemInList<T>(IEnumerable<T> anyType)
{
// do work
}
这仍然允许您使用foreach
,但允许您的方法更灵活,因为它可以工作List<T>
,但也可以使用任何其他实现IEnumerable<T>
的集合。如果您必须在方法中使用列表语义,则可以使用IList<T>
,但您的示例代码(和方法名称)建议IEnumerable<T>
更合适。