C#泛型基础
C#语言推出泛型已经有好多年了。泛型的推出可以说是一项创举,可是实际上我们经常是怎样使用泛型的呢。?。
之前也常用一些泛型的基本用法,语法也看过一段时间。但是毕竟还是有很多”高级“一些的用法没怎么用过。最近做一个基于微软MCS架构的项目时,很多都给封装好了,包括常用的TextBox也被微软那帮人给重写了。由于大量的重写,所以难免会有大量的泛型等等大量的运用。看到被封装好的源码,也难免不去梳理一下相关知识。这一节主要包括一下几个部分:
1、泛型约束
2、new关键字.
3、default关键字的用法
以上是c#泛型最基本的几个知识点.下面将说说这些概念的理解以、关键字。
1、泛型约束.
何谓泛型约束呢。?泛型约束是我们在定义泛型类时,在实际泛型类的使用过程中,对泛型类类型的一些约束。
泛型约束是通过泛型类定义来体现的。请看下面代码中泛型约束的定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | public class BaseClass { public BaseClass() { Console.WriteLine( "Abstractor constructor method" ); } public void Method() { Console.WriteLine( " method in Base Class" ); } } public class TestSubClass : BaseClass { //public override void Method() //{ // Console.WriteLine("testSubClass method"); //} } public class Cat { public void CatEat() { Console.WriteLine( "CatEat method" ); } } public class SubClass<T> where T:BaseClass { public T instance; public void subMethod() { Console.WriteLine( "subClass" ); } } |
其中 SubClass<T>就是一个自定义类,T为泛型类型,where T:BaseClass就是定义的泛型类的约束。意思就是说在使用SubClass<T>时候,我们必须用BaseClass或者BaseClass的子类来对SubClass<T>进行实例化。
使用如下:
1 2 3 4 5 6 | SubClass<BaseClass> cast = new SubClass<BaseClass>(); cast.subMethod(); SubClass<TestSubClass> cast2 = new SubClass<TestSubClass>(); cast2.subMethod(); Console.WriteLine( "aa" ); Console.ReadLine(); |
输出如下:
2、new关键字。
new关键字的作用是值对泛型类型的默认构造函数。类型定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | public abstract class BaseClass { public BaseClass() { Console.WriteLine( "Abstractor constructor method" ); } public virtual void Method() { Console.WriteLine( "Method in Abastact class" ); } } public class TestSubClass : BaseClass { public TestSubClass() { } } public class SubClass<T> where T:BaseClass, new () { public T instance; public void subMethod() { Console.WriteLine( "subClass" ); if (instance == null ) { instance = new T(); instance.Method(); Console.WriteLine(instance.GetType().ToString()); } } } |
.new () 的意思是说泛型类型T必须要有一个无参数构造函数。
输出如下:
此时,需要注意的是在用TestSubClass替换泛型类型T实例化 SubClass<T>时候,可以在TestSubClass中不定义任何构造函数,但是若我们要定义带参数的构造函数时,一定同时要有不带参数构造函数。因为我们不定义构造函数时,.Net FrameWork会默认有一个无参数构造函数,但是如果我们定义了一个带参数的,则它只有这个构造函数了,这是C#语法开遍就介绍过了。
另外:在使用new进行约束时,不能带有带参数的构造函数。
3、default关键字的使用。
首先给出MSDN给出的介绍:
在泛型类和泛型方法中产生的一个问题是,在预先未知以下情况时,如何将默认值分配给参数化类型 T:
-
T 是引用类型还是值类型。
-
如果 T 为值类型,则它是数值还是结构。
给定参数化类型 T 的一个变量 t,只有当 T 为引用类型时,语句 t = null 才有效;只有当 T 为数值类型而不是结构时,语句 t = 0 才能正常使用。解决方案是使用 default 关键字,此关键字对于引用类型会返回空,对于数值类型会返回零。对于结构,此关键字将返回初始化为零或空的每个结构成员,具体取决于这些结构是值类型还是引用类型。以下来自 GenericList<T> 类的示例显示了如何使用 default 关键字。
首先看看它的用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class TestGeneric<T> { public T GetValue() { T instance = default (T); if (instance == null ) { Console.WriteLine( " instance is null" ); } else { Console.WriteLine( "value of instance is {0}" ,instance); } return instance; } } } TestGeneric< string > instance = new TestGeneric< string >(); instance.GetValue(); Console.ReadLine(); |
如果将泛型类型string换位int,则输出如下:
那么如果我们用struct类型替换泛型类型会是什么情况呢。?
可以定义一个struct试试:
代码如下:
1 2 3 4 5 6 7 8 9 | public struct Point { public int X { get ; set ; } public int Y { get ; set ; } } TestGeneric<Point> instance = new TestGeneric<Point>(); instance.GetValue(); Console.ReadLine(); |
struct是一种值类型的,所以它不会像string等引用类型使用default的时候会为null。
好了,就到这里,希望对初学泛型的朋友有一些帮助!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构