C# 如何设置类型为列表的泛型约束? private static void printedeachitemlist(T anyList) 其中T:System.Collections.Generic.List { foreach(t中的变量t) { //做任何事 } }

C# 如何设置类型为列表的泛型约束? private static void printedeachitemlist(T anyList) 其中T:System.Collections.Generic.List { foreach(t中的变量t) { //做任何事 } },c#,generics,C#,Generics,在上面的代码中(这是错误的),我只想设置一个约束,即T是一个列表 目的不是让这个示例工作,目的是了解如何设置类型为列表的约束?我是泛型方面的业余爱好者,正在努力解决问题:(将您的输入参数声明为IList。如果您想使输入序列尽可能抽象,请使用IEnumerable而不是IList 私有静态void printeAchitemList(IList序列) { foreach(序列中的T元素) { //做任何事 } } 您通常会这样写: private static void PrintEachIte

在上面的代码中(这是错误的),我只想设置一个约束,即
T
是一个列表


目的不是让这个示例工作,目的是了解如何设置类型为列表的约束?我是泛型方面的业余爱好者,正在努力解决问题:(

将您的输入参数声明为
IList
。如果您想使输入序列尽可能抽象,请使用
IEnumerable
而不是
IList

私有静态void printeAchitemList(IList序列)
{
foreach(序列中的T元素)
{
//做任何事
}
} 

您通常会这样写:

private static void PrintEachItemInList<T>(IList<T> sequence)
{
    foreach (T element in sequence)
    {
        //Do whatever
    }
} 
private static void printeAchitemList(列表任意类型)
{
//工作
}
但是,在这种情况下,我建议使用
IEnumerable

private static void PrintEachItemInList<T>(List<T> anyType)
{
  // do work
}
private static void printeAchitemList(IEnumerable anyType)
{
//工作
}

这仍然允许您使用
foreach
,但允许您的方法更加灵活,因为它不仅可以使用
List
,还可以使用实现
IEnumerable
的任何其他集合。如果您必须在方法中使用List语义,则可以使用
IList
,但不能使用示例代码(和方法名称)建议使用
IEnumerable
更合适。

您的函数应该只接受一个列表,而不需要约束:

private static void PrintEachItemInList<T>(IEnumerable<T> anyType)
{
  // do work
}
private static void printeAchitemList(IList列表)
{
foreach(列表中的变量t)
{
//做任何事
}
}
但是,如果只想迭代列表,可以通过将参数类型更改为以下基本接口之一,使代码更通用:

  • IEnumerable
    -允许
    foreach
  • IReadOnlyCollection
    -同上,并提供集合中元素的计数
  • IReadOnlyList
    -同上,允许通过索引访问元素
  • ICollection
    -一种
    IEnumerable
    ,提供元素计数以及添加和删除元素的方法
  • IList
    -同上,允许您按索引添加和删除元素
可能需要两个类型参数,如中所示:

private static void PrintEachItemInList<T>(IList<T> list) 
{
    foreach (var t in list)
    {
        //Do whatever
    }
}
private static void printedeachitemlist(TList anyType)
其中TList:System.Collections.Generic.List
<>这是有用的,如果您使用的是从List中派生的类。如果您想要任何作为列表的东西,请考虑约束到接口<代码> ILIST < /COD>。然后它将用于<代码>列表、一维数组和实现接口的自定义类。(但不一定来自
列表

Edit:正如注释所指出的,该方法使用起来很麻烦,因为编译器不会推断这两个类型参数,因此在调用该方法时必须显式给出它们

考虑只使用:

private static void PrintEachItemInList<TList, TItem>(TList anyType) 
  where TList : System.Collections.Generic.List<TItem>
private static void printeAchitemList(列表任意类型)
由于从
列表
派生的任何内容都可以分配给
列表
,因此可以使用派生类作为参数来调用该方法,并且在许多情况下,编译器可以自动推断类型
TItem

仍然考虑使用接口<代码> IIST

如果要执行的全部操作都是从列表中读取,请使用
IReadOnlyList
而不是
IList
。这会向调用者发出您不会更改其列表的信号。调用时仍然不需要强制转换语法,例如:
PrintEachItemInList(新[]{2,3,5,7,})
IReadOnlyList类型是.NET版本4.5中的新类型

如果您只想从列表中读取,而不想使用索引器(no
anyType[idx]
),也不想使用
.Count
属性,事实上,您只想通过列表使用
foreach
,那么请使用
IEnumerable
。再次,您表示您不会更改人们的列表


IReadOnlyList
IEnumerable
在其泛型参数(类型参数)中都是协变的。

如果要使用参数多态性来表示该约束,在c中需要两个类型参数(因为您没有获得高阶类型):

private static void printeAchitemList(X anyType),其中X:System.Collections.Generic.List
{
foreach(任何类型中的变量t)
{
Console.WriteLine(t.ToString());
}
}
但是你需要这样打电话:

private static void PrintEachItemInList<X, T>(X anyType) where X:System.Collections.Generic.List<T>
{

             foreach (var t in anyType)
            {
                Console.WriteLine(t.ToString());
            }
}
printeAchitemList(新列表(){“a”、“b”});

如何定义“列表”?
IList
list
?对于一般约束,后者很可能是一个错误的选择。或者
IEnumerable
就足够了吗?(任何一个都可以,但是我更喜欢IListy您的约定对于您的参数来说是令人困惑的,
T anyType
实际上是
T anyListType
?我知道这一点,但我想知道的是如何将其设置为对T的约束。使用什么约束?为了限制封闭类型,可以将其应用于开放类型。如果以上输入类型仅限于IList。这是在中实现扩展方法的方式LINQ@developer747这不是在t上设置约束吗,因为它只能是IList中包装的任何类型?或者我缺少了您的另一个要求吗?+1他,你抢先一步…+1对不起,但此代码要求您指定泛型参数显式(无类型推断)调用此方法
printeachiteminist(新列表{1,2,3});
@DavidL这是在java中,具体化泛型实际上没有帮助的少数情况之一
private static void PrintEachItemInList<TItem>(List<TItem> anyType) 
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"});