什么是泛型?(c#概念)

author author     2023-02-14     508

关键词:

不要MSDN,CSDN上的概念。要比较容易懂的解释或者比方。

在给你比较好懂的:
通过泛型可以定义类型安全类,而不会损害类型安全、性能或工作效率。您只须一次性地将服务器实现为一般服务器,同时可以用任何类型来声明和使用它。为此,需要使用 < 和 > 括号,以便将一般类型参数括起来。例如,可以按如下方式定义和使用一般堆栈:
public class Stack T[] m_Items; public void Push(T item) ... public T Pop() ...Stack stack = new Stack();stack.Push(1);stack.Push(2);int number = stack.Pop();
代码块 2 显示一般堆栈的完整实现。将代码块 1 与代码块 2 进行比较,您会看到,好像 代码块 1 中每个使用 Object 的地方在代码块 2 中都被替换成了 T,除了使用一般类型参数 T 定义 Stack 以外:
public class Stack...
在使用一般堆栈时,必须通知编译器使用哪个类型来代替一般类型参数 T(无论是在声明变量时,还是在实例化变量时):
Stack stack = new Stack();
编译器和运行库负责完成其余工作。所有接受或返回 T 的方法(或属性)都将改为使用指定的类型(在上述示例中为整型)。
代码块 2. 一般堆栈
public class Stack readonly int m_Size; int m_StackPointer = 0; T[] m_Items; public Stack():this(100) public Stack(int size) m_Size = size; m_Items = new T[m_Size]; public void Push(T item) if(m_StackPointer >= m_Size) throw new StackOverflowException(); m_Items[m_StackPointer] = item; m_StackPointer++; public T Pop() m_StackPointer--; if(m_StackPointer >= 0) return m_Items[m_StackPointer]; else m_StackPointer = 0; throw new InvalidOperationException("Cannot pop an empty stack");

注 T 是一般类型参数(或类型参数),而一般类型为 Stack。Stack 中的 int 为类型实参。
该编程模型的优点在于,内部算法和数据操作保持不变,而实际数据类型可以基于客户端使用服务器代码的方式进行更改。
泛型实现
表面上,C# 泛型的语法看起来与 C++ 模板类似,但是编译器实现和支持它们的方式存在重要差异。正如您将在后文中看到的那样,这对于泛型的使用方式具有重大意义。
注 在本文中,当提到 C++ 时,指的是传统 C++,而不是带有托管扩展的 Microsoft C++。
与 C++ 模板相比,C# 泛型可以提供增强的安全性,但是在功能方面也受到某种程度的限制。
在一些 C++ 编译器中,在您通过特定类型使用模板类之前,编译器甚至不会编译模板代码。当您确实指定了类型时,编译器会以内联方式插入代码,并且将每个出现一般类型参数的地方替换为指定的类型。此外,每当您使用特定类型时,编译器都会插入特定于该类型的代码,而不管您是否已经在应用程序中的其他某个位置为模板类指定了该类型。C++ 链接器负责解决该问题,并且并不总是有效。这可能会导致代码膨胀,从而增加加载时间和内存足迹。
在 .NET 2.0 中,泛型在 IL(中间语言)和 CLR 本身中具有本机支持。在编译一般 C# 服务器端代码时,编译器会将其编译为 IL,就像其他任何类型一样。但是,IL 只包含实际特定类型的参数或占位符。此外,一般服务器的元数据包含一般信息。
客户端编译器使用该一般元数据来支持类型安全。当客户端提供特定类型而不是一般类型参数时,客户端的编译器将用指定的类型实参来替换服务器元数据中的一般类型参数。这会向客户端的编译器提供类型特定的服务器定义,就好像从未涉及到泛型一样。这样,客户端编译器就可以确保方法参数的正确性,实施类型安全检查,甚至执行类型特定的 IntelliSense。
有趣的问题是,.NET 如何将服务器的一般 IL 编译为机器码。原来,所产生的实际机器码取决于指定的类型是值类型还是引用类型。如果客户端指定值类型,则 JIT 编译器将 IL 中的一般类型参数替换为特定的值类型,并且将其编译为本机代码。但是,JIT 编译器会跟踪它已经生成的类型特定的服务器代码。如果请求 JIT 编译器用它已经编译为机器码的值类型编译一般服务器,则它只是返回对该服务器代码的引用。因为 JIT 编译器在以后的所有场合中都将使用相同的值类型特定的服务器代码,所以不存在代码膨胀问题。
如果客户端指定引用类型,则 JIT 编译器将服务器 IL 中的一般参数替换为 Object,并将其编译为本机代码。在以后的任何针对引用类型而不是一般类型参数的请求中,都将使用该代码。请注意,采用这种方式,JIT 编译器只会重新使用实际代码。实例仍然按照它们离开托管堆的大小分配空间,并且没有强制类型转换。
泛型的好处
.NET 中的泛型使您可以重用代码以及在实现它时付出的努力。类型和内部数据可以在不导致代码膨胀的情况下更改,而不管您使用的是值类型还是引用类型。您可以一次性地开发、测试和部署代码,通过任何类型(包括将来的类型)来重用它,并且全部具有编译器支持和类型安全。因为一般代码不会强行对值类型进行装箱和取消装箱,或者对引用类型进行向下强制类型转换,所以性能得到显著提高。对于值类型,性能通常会提高 200%;对于引用类型,在访问该类型时,可以预期性能最多提高 100%(当然,整个应用程序的性能可能会提高,也可能不会提高)。本文随附的源代码包含一个微型基准应用程序,它在紧密循环中执行堆栈。该应用程序使您可以在基于 Object 的堆栈和一般堆栈上试验值类型和引用类型,以及更改循环迭代的次数以查看泛型对性能产生的影响。
参考技术A 2.0 版 C# 语言和公共语言运行库 (CLR) 中增加了泛型。泛型将类型参数的概念引入 .NET Framework,类型参数使得设计如下类和方法成为可能:这些类和方法将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法的时候。例如,通过使用泛型类型参数 T,您可以编写其他客户端代码能够使用的单个类,而不致引入运行时强制转换或装箱操作的成本或风险,如下所示:

C# 复制代码
// Declare the generic class.
public class GenericList<T>

void Add(T input)

class TestGenericList

private class ExampleClass
static void Main()

// Declare a list of type int.
GenericList<int> list1 = new GenericList<int>();

// Declare a list of type string.
GenericList<string> list2 = new GenericList<string>();

// Declare a list of type ExampleClass.
GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();



泛型概述
使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。

泛型最常见的用途是创建集合类。

.NET Framework 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。应尽可能地使用这些类来代替普通的类,如 System.Collections 命名空间中的 ArrayList。

您可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。

可以对泛型类进行约束以访问特定数据类型的方法。

关于泛型数据类型中使用的类型的信息可在运行时通过使用反射获取。
参考技术B 下面的代码示例演示客户端代码如何使用泛型 GenericList<T> 类来创建整数列表。只需更改类型参数,即可方便地修改下面的代码示例,创建字符串或任何其他自定义类型的列表:

C# 复制代码
class TestGenericList

static void Main()

// int is the type argument
GenericList<int> list = new GenericList<int>();

for (int x = 0; x < 10; x++)

list.AddHead(x);


foreach (int i in list)

System.Console.Write(i + " ");

System.Console.WriteLine("\nDone");

参考技术C 泛型编程让你编写完全一般化并可重复使用的算法,其效率与针对某特定数据类型而设计的算法相同。泛型编程的代表作品STL是一种高效、泛型、可交互操作的软件组件。所谓泛型(Genericity),是指具有在多种数据类型上皆可操作的含意,与模板有些相似。STL巨大,而且可以扩充,它包含很多计算机基本算法和数据结构,而且将算法与数据结构完全分离,其中算法是泛型的,不与任何特定数据结构或对象类型系在一起。STL以迭代器(Iterators)和容器(Containers)为基础,是一种泛型算法(Generic Algorithms)库,容器的存在使这些算法有东西可以操作。STL包含各种泛型算法(algorithms)、泛型指针(iterators)、泛型容器(containers)以及函数对象(function objects)。STL并非只是一些有用组件的集合,它是描述软件组件抽象需求条件的一个正规而有条理的架构。

java中什么是泛型

一.泛型概念的提出(为什么需要泛型)?首先,我们看下下面这段简短的代码:1publicclassGenericTest{23publicstaticvoidmain(String[]args){4Listlist=newArrayList();5list.add("qqyumidi");6list.add("corn");7list.add(100);89for(inti=0;i<list. 查看详情

c#语言中泛型和委托的关系是啥,func<int>是泛型还是委托?

C#语言中泛型和委托的关系是什么,Func是泛型还是委托?参考技术AFunc既是泛型也是委托。表示一个没有参数,有int返回值的函数。 查看详情

什么是泛型?泛型的基本原理与使用优势。(代码片段)

目录 1.什么是泛型?2.先来看一个简单的泛型例子3.那么T是什么呢?4.如何使用泛型,并将类型作为参数传入呢?5.泛型的基本原理6.使用泛型的好处1.什么是泛型?泛型将接口的概念进一步延伸,“泛型”... 查看详情

c#泛型

...作一个形容词 这样比较方便理解因为很多东西都可以是泛型的比如--“泛 查看详情

sql多表查询出来的数据在c#中用啥装载比较好,是泛型集合还是集合??还有其他的可以装吗??

...泛型集合,还是普通的集合,我想你只要理解了泛型是个什么东西,就知道该用什么了,我认为有泛型的地方,就不用普通的hashtable,arraylist.参考技术A最好就是用dataset或是datareader了,什么泛型之类的东西最好还是不用,意义不... 查看详情

c#学习(10):委托

1。疑问:1.委托是什么?2.为什么需要委托?3.委托能用来做什么?4.如何自定义委托?5..NET默认的委托类型有哪几种?6.怎样使用委托?7.多播委托是什么?8什么是泛型委托?9.什么是匿名方法?10.委托是否可以回调实例方法?11.L... 查看详情

什么是泛型

Java泛型(generics)是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter)。声明的类型参数在使用时用具体的类型来替换。 泛型的本质是参数化类型,也就是说所操作的数据类型被指定... 查看详情

c#之泛型

什么是泛型我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int数据,另一个是处理string数据,或者其他自定义的数据类型,但我们没有办法,只能分别写多个方法处理每个数据类型,因为方法的参数类型... 查看详情

.netc#杂谈:变体

...其对C#的意义1.阅读基础了解C#进阶语言功能的使用(尤其是泛型、委托、接口)2.从示例入手,理解变体变体这一概念用于描述存在继承关系的类型间的转化,这一概念并非只适用于C#,在许多其他的OOP语言中也都有变体概念。... 查看详情

c#泛型详解(代码片段)

...中有很重要的地位,尤其是在搭建项目框架的时候。一、什么是泛型泛型是C#2.0推出的新语法,不是语法糖,而是2.0由框架升级提供的功能。我们在编程程序时,经常会遇到功能非常相似的模块,只是它们处理的数据不一样。但... 查看详情

c#之泛型详解

什么是泛型      我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int数据,另一个是处理string数据,或者其他自定义的数据类型,但我们没有办法,只能分别写多个方法处理每个数据... 查看详情

c#泛型比较大小

 usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespace泛型比较大小{classProgram{//Compare<T>是泛型类,T为类型参数publicclassCompare<T>whe 查看详情

关于泛型,什么是泛型,如何理解泛型,直接上代码举例

泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型,就不至于在运行时出现转换异常, 它的本质是参数化类型(即以任何类型T作为参数,<T>,在使用时可以传入类型T的... 查看详情

为啥 NIO.2 FileVisitor 类型是泛型的?

...型是泛型的?【英文标题】:WhyisNIO.2FileVisitortypegeneric?为什么NIO.2FileVisitor类型是泛型的?【发布时间】:2013-04-3015:57:05【问题描述】:我正在研究JavaNIO.2及其文件操作,目前我正在使用文件树遍历函数和类。NIO.2FileVisitorAPI很棒... 查看详情

c++泛型编程(代码片段)

目录1.什么是泛型编程?2.函数模板(1)函数模板概念(2)函数模板格式(3)函数模板的原理(4)函数模板的实例化1)隐式实例化:让编译器根据实参推演模板参数的实际类型2)显式实例化:在函数名后的<>中指定模板参数... 查看详情

c++泛型编程(代码片段)

目录1.什么是泛型编程?2.函数模板(1)函数模板概念(2)函数模板格式(3)函数模板的原理(4)函数模板的实例化1)隐式实例化:让编译器根据实参推演模板参数的实际类型2)显式实例化:在函数名后的<>中指定模板参数... 查看详情

泛型就这么简单(代码片段)

...是高深的知识,如果基础好的同学可以当复习看看~一、什么是泛型?Java泛型设计原则:只要在编译时期没有出现警告,那么运行时期就不会出现ClassCastExce 查看详情

《精通c#》第十二章linq

...以使用linq,简单来说就是实现IEnumerable<T>接口。那么什么是泛型?什么是非泛型?先说说非泛型,是.Net2.0之前一直在使用的集合类,它的特点在于它在存储数据的时候不需要指定数据的类型,甚至在一个集合内 查看详情