.NET Framework泛型

✍ dations ◷ 2025-07-09 21:22:49 #.NET Framework泛型

.NET Framework泛型是在.NET Framework 2.0的公共语言运行库(CLR)中的增加的一项新功能,类似于C++的模板,但不如C++的模板灵活,不过也有一些自己的特性。

泛型为.NET Framework引入了类型参数的概念,这样便可以设计出这样的类和方法:它们把指定类型的工作推迟到客户端代码声明并实例化类或方法的时候执行。比如,通过泛型类型参数T,程序员就可以编写其他客户端代码能够使用的单个类,而不用担心强制转换或装箱操作而带来的额外的运行成本或风险。

泛型类和方法较之非泛型类和方法具有更高的可用性、类型安全和效率,且通常用在集合和集合上运行的方法中。在.NET Framework2.0的类库中添加了一个新的命名空间System.Collections.Generic,其中含有一些新的基于泛型的集合类。微软建议程序员在设计面向.NET Framework 2.0的应用程序时不要使用旧的非泛型集合类(像ArrayList集合类),而去使用新的泛型集合类。

当然,程序员也可以创建自己的泛型类和方法,提供自己需要的解决方案,但微软不推荐自己创建泛型类,而建议使用.NET Framework类库中提供的List<T>类。

可以通过泛型类型参数传递一个类型(如一个类TestClass<T>)中的T是泛型的类型参数,可以通过它传递一个类型(如int),那么,在这个类中所有用类型参数(在本例中是T)定义的字段或方法等的类型都会根据传递进来的类型(本例中为int类型)所改变。

在定义泛型类或方法中,类型参数是客户端程序实例化泛型类变量时指定的类型占位符。泛型类不能像通常的类那样使用,因为它实际上并不是一个类型,可能更像一个类型的蓝图。要使用泛型类,客户端代码必须要指定尖括号中的类型参数并实例化类型才能构造类型。指定的类型参数可以是编译器可以识别的任何类型,并且可以构造任意数目的使用不同类型参数的实例。

通常,微软推荐采用如下命名规则:

对于泛型参数的约束是指对客户端代码实例化类时指定的类型参数进行限制,这样如果客户端的程序参试使用某个不允许使用的类型实例化类时会产生编译时错误。

以C# 为例,约束采用where上下文关键字指定。

若要对泛型列表中的项与其他某个项进行比较,便需要在一定程度上保证所调用的运算符或方法可以得到指定的类型参数的支持。这个保证正是建立在对泛型类定义的一个或多个约束获得的。一旦编译器得到了这样的保证,它就能够允许在泛型类中调用一些无约束的泛型中不允许使用的方法。

没有进行约束的泛型类型参数称为未绑定的类型参数。

当使用未绑定的类型参数时,相对于使用了约束的类型参数,有以下规则:

泛型类可以拥有至少一个泛型类型参数,泛型类型参数可以代替泛型类的字段、属性、方法的参数和返回值、事件的参数和返回值、构造函数的参数的类型,也可作为内部类和基类以及实现接口的泛型类型参数。

泛型类必须在创建其实例时明确指定其所有泛型类型参数的类型。泛型类的构造函数不能自动推断其泛型类型的泛型类型参数。

如果从泛型类派生,可以选择确定的泛型类型参数,也可以用泛型派生类,利用泛型派生类的泛型类型参数确定基类的泛型类型参数。

泛型接口的使用大体上与泛型类相同,只是接口不允许包含字段和构造函数,也不允许创建实例。实现接口时,同样也可以选择实现确定的泛型类型接口,或者利用泛型类型参数确定接口的泛型类型参数。

泛型方法可以拥有至少一个泛型类型参数,泛型类型参数可以作为方法的参数或返回值的类型。泛型方法不用明确指定各泛型类型参数,可由上下文自动推断,如果上下文无法自动推断,则必须明确指定。

泛型委托的使用大体上与泛型方法相同,泛型委托的泛型类型参数可以在创建时通过上下文自动推断。泛型委托实例总是具有确定的泛型类型参数。

泛型和模板都是用于提供类型参数支持的语言功能,但这两者有着诸多差异。

从语法层面上来说,一般认为泛型是一种相对模板简单的方法,而不具有模板的复杂性。但同时,泛型也不能提供模板的完整功能。

另一方面,从实现层面,泛型的替换是在运行时执行的,这样可以为实例化的对象保留泛型类型的信息。

下面列出了.NET Framework泛型和C++模板之间的主要区别:

泛型类型参数自身不能是泛型,但C++确实允许模板参数。

C++允许程序员编写可能对模板中某些类型参数无效的代码,然后将检查该代码中是否有用作类型参数的特定类型。比如说可以在C++中编写对类型参数对象的算术运算符的函数,这样在用不支持这些运算符的类型实例化模板时出现出现错误;而泛型是不允许这样的,它则要求相应地编写类当中的代码,使他们能够满足任何约束的类型。因此唯一允许的语言构造是那些能够从约束中推导出来的结构。

相关

  • 共轭先验在贝叶斯统计中,如果后验分布与先验分布属于同类,则先验分布与后验分布被称为共轭分布,而先验分布被称为似然函数的共轭先验(Conjugate prior)。比如,高斯分布家族在高斯似然函数
  • 大隅号大隅号是一颗在1970年2月11日时由东京大学宇宙航空研究所自鹿儿岛宇宙空间观测所使用L-4S型火箭五号机发射升空的人造卫星大隅五号,也是日本最初的人造卫星。名称取自于发射
  • 吕宋海槽吕宋海槽(Luzon Strait),是台湾岛和吕宋岛之间的海槽,被其中的巴丹群岛和巴布延群岛又分为巴士海峡、巴林塘海峡和巴布延海峡三条水道。吕宋海槽东接太平洋,西通南中国海,全宽约25
  • 王仕鹏王仕鹏(1983年4月6日-),生于辽宁省丹东市,前中国国家男子篮球队成员,曾效力于广东东莞银行队。曾参加2006年日本世锦赛和2008年北京奥运会。2006年8月24日,在中国对阵斯洛文尼亚的
  • 宇宙流宇宙流是围棋的一种布局作战的方式,是在1970年代由日本围棋手武宫正树所创造及发展。在宇宙流出现之前的围棋战法,大多重视实利,亦即以第三线为主的布局方式,以求在边上取得地盘
  • 云嘉调频广播电台云嘉调频广播电台(英文:Yeue-Chia Broadcasting),简称云嘉电台,经营公司名云嘉广播股份有限公司,是台湾的FM地区性电台,总部位于嘉义市。发送区域以云林县、嘉义县、嘉义市、台南市
  • 希腊左巴《希腊左巴》(希腊语:)是希腊作家卡山札基的小说,1946年出版。描写左巴和英国人K君在克里特岛上的生活。1964年,改编为同名电影。
  • 关目高殿站关目高殿站(日语:関目高殿駅/せきめたかどのえき  */?)是一个位于日本大阪府大阪市旭区高殿,属于大阪市高速电气轨道(大阪地下铁)的铁路车站。车站编号是T15。“关目”位于城东区
  • 里巴茨科耶站里巴茨科耶站(俄语:Рыба́цкое,罗马化:Rybatskoye)是圣彼得堡地铁的一个车站。里巴茨科耶站开通于1984年12月28日,是圣彼得堡地铁3号线的车站,为地上车站。
  • 猪洞河猪洞河,也作猪拱河,位于中国山东省平度市东北部,是小沽河右岸支流,发源于平度与莱州交界处的大泽山南麓,东南流经大田镇、尹府水库和云山镇,于小河子村入小沽河。全长37.5公里,流域