如何设置类型为List的一般约束? [英] How to set a generic constraint that the type is a List?

查看:54
本文介绍了如何设置类型为List的一般约束?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 私有静态无效PrintEachItemInList< T>(T anyList)其中T:System.Collections.Generic.List< T>{foreach(T中的var t){//做任何事情}} 

在上面的代码中(这是错误的),我想要做的就是设置 T 是列表的约束.

目的不是使该示例正常工作,目的是了解如何设置类型为列表的约束?我是泛型的业余爱好者,正在尝试弄清楚:(

解决方案

也许您想要两个类型的参数,例如:

 私有静态无效PrintEachItemInList< TList,TItem>(TList anyType)其中TList:System.Collections.Generic.List< TItem> 

如果您使用实际上从 List<> 派生的类,这将很有用.如果您希望将作用作为列表,请考虑限制为接口 IList<> .然后,它将适用于 List<> ,一维数组和实现该接口的自定义类(但不一定来自 List<> ).

如评论所指出,此方法使用起来很麻烦,因为编译器不会推断两个类型参数,因此在调用该方法时必须显式给出它们./p>

考虑只使用:

 私有静态无效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<> 在它们的通用参数(类型参数)中都是协变变量.

private static void PrintEachItemInList<T>(T anyList) 
Where T:System.Collections.Generic.List<T>
{    
    foreach (var t in T)
    {
        //Do whatever
    }
}

In the above code (which is wrong) all I want to do it to set a constraint that T is a List.

The aim is not to get this example to work, the aim is to understand how can I set a constraint that the type is a list? I am an amateur in generics and am trying to figure things out :(

解决方案

Maybe you want two type parameters, as in:

private static void PrintEachItemInList<TList, TItem>(TList anyType) 
  where TList : System.Collections.Generic.List<TItem>

This is useful if you use classes that actually derive from List<>. If you want anything that acts as a list, consider constraining to the interface IList<> instead. It will then work for List<>, single-dimensional arrays, and custom classes implementing the interface (but not necessarily deriving from List<>).

Edit: As pointed out by the comment, this method is cumbersome to use because the compiler will not infer the two type arguments, so they will have to be given explicitly when calling the method.

Consider just using:

private static void PrintEachItemInList<TItem>(List<TItem> anyType) 

Because anything which derives from a List<> is assignable to List<>, the method can be called with derived classes as arguments, and in many cases the type TItem can be inferred automatically by the compiler.

Still consider using the interface IList<>.

If all you want to do, is read from the list, use IReadOnlyList<TItem> instead of IList<TItem>. This signals to the caller that you won't change his list. Still no cast syntax is required when calling, for example: PrintEachItemInList(new[] { 2, 3, 5, 7, });. The type IReadOnlyList<> is new in .NET version 4.5.

If all you want to do is read from the list, and you don't want to use the indexer (no anyType[idx]), and you don't want to use the .Count property, and in fact, all you want to do is foreach through the list, use IEnumerable<TItem>. Again, you signal that you won't change people's lists.

Both IReadOnlyList<> and IEnumerable<> are covariant in their generic argument (type parameter).

这篇关于如何设置类型为List的一般约束?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆