C# LINQ中ToList<ClassName>显式指定类名的作用是什么?
LINQ中ToList()显式指定泛型参数的作用说明
我在查看如下代码示例:
// Student collection IList<Student> studentList = new List<Student>() { new Student() { StudentID = 1, StudentName = "John", Age = 13} , new Student() { StudentID = 2, StudentName = "Moin", Age = 21 } , new Student() { StudentID = 3, StudentName = "Bill", Age = 18 } , new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} , new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } }; // LINQ Method Syntax to find out teenager students var teenAgerStudents = studentList.Where(s => s.Age > 12 && s.Age < 20) .ToList<Student>();
我发现上述代码中的.ToList<Student>()也可以直接简写为.ToList();,想知道调用ToList<ClassName>方法时显式传入类名作为泛型参数的具体作用是什么。
解答
这个写法的逻辑和C#的泛型类型推断机制直接相关,分情况说明:
- 你贴的这段示例里,显式传入
<Student>没有任何实际作用
前面的Where(s => s.Age > 12 && s.Age < 20)执行后返回的本来就是IEnumerable<Student>类型,编译器能完全准确推断出ToList()的泛型参数就是Student,这时候写不写<Student>,最终编译生成的执行代码完全一致。这种写法要么是早期接触LINQ的开发者留下的书写习惯,要么是代码生成工具输出代码时不会自动省略显式参数而已。 - 只有两类场景下,显式给
ToList()传泛型参数才有实际价值:- 编译器无法自动推断目标类型的时候。比如你操作的是非泛型的
IEnumerable集合(比如老式的ArrayList),或者逻辑里涉及匿名类型、类型层级太复杂导致编译器推断失败,这时候显式传入类型参数,才能明确告诉编译器要生成什么类型的返回集合。 - 你需要强制指定返回集合的元素类型的时候。比如你手里的序列声明为协变的父类/接口类型,实际存储的都是子类实例,直接调用
ToList()会返回父类/接口类型的列表,这时候显式传入子类类型,ToList()会自动完成类型转换,返回你指定类型的集合,比额外调用Cast<T>()更简洁。反过来如果你要把子类序列转成父类类型的列表,也可以显式指定父类作为泛型参数,编译器会在编译阶段做类型兼容性检查,类型不兼容会直接报编译错误,比运行时才抛异常安全得多。
- 编译器无法自动推断目标类型的时候。比如你操作的是非泛型的
内容的提问来源于stack exchange,提问作者variable
相关产品推荐
相关产品推荐

