外链代发包收录,纯手工外链代发就找老客外链吧

站长新闻

您的位置:老客外链吧 > 站长新闻 > 科技 >

看完这篇,终于知道自己会不会 C# 泛型了!

文章来源:老客SEO 作者:老客SEO 人气:16 时间2019-07-30 13:00:27

作者 | 羽生结弦

责编 | 胡巍巍

在开发过程中,同一段代码处出现多次调用,并且会有不同的类型在使用,这种就叫做跨类型代码复用。一般情况下跨类型代码复用我们会用到如下两种方法:

1. 继承;

2. 泛型。

继承是通过父类来代表代码复用,而泛型是通过带有占位符的模板来代码复用,其中占位符指的是类型。

比如:int、syting和实体等。本片主要讲解泛型的相关知识,下面就来详细讲解一下泛型。

零、泛型类型

泛型会声明类型参数,消费者需要提供类型参数来把占位符类型填充上。我们先来看一个例子:

publicclassGenericClass<T>

{

T[] tArray=newT[10];

intposition=0;

publicvoidPush(T t)=>tArray[position++]=t;

publicPop=>tArray[--position];

publicT[] GetTs => tArray;

}

classProgram

{

staticvoidMain(string[] args)

{

var genericStr=newGenericClass<string>;

generic.Push("张三");

generic.Push("李四");

generic.Push("王五");

generic.Pop;

var genericInt=newGenericClass<int>;

generic.Push(1);

generic.Push(2);

generic.Push(3);

generic.Pop;

}

}

在上面的代码中当我们将string传入泛型类中,将会隐式动态的创建类型,这种操作被称为合成,合成将发生在运行时,而非编译时。当我们在代码中传入非string类型的值时,在编译时将报错。同样在上面的代码中我们也看到了int传入泛型类中的情况,这就说明泛型类可以跨类型复用。

小知识1:

我们将GenericClass<T>称为开放类型(OpenType),而将GenericClass<string>称为封闭类型(CloseType),开放类型在编译后就变成了封闭类型,在运行时所有的泛型类型都是封闭类型,因为占位符已经被具体类型填充完毕。

小知识2:

对于每一种封闭类型,静态数据都是唯一的,例如:

classProgram

{

staticvoidMain(string[] args)

{

// 输出1

Console.WriteLine(++MyClass<int>.Count);

// 输出2

Console.WriteLine(++MyClass<int>.Count);

// 输出1

Console.WriteLine(++MyClass<string>.Count);

}

}

classMyClass<T>

{

publicstaticintCount;

}

上面代码中,MyClass中存在一个静态字段Count,我们看到前两次的调用输出的分别是1和2,但是第三次输出的确实1,那么这是为什么呢,原因就是前两次的类型参数和泛型类型种的静态字段的类型一致,而第三次的类型参数不一致导致的。

在泛型类型饿子类中可以继续让父类参数保持开放,也剋及关闭父类的类型参数,同样子类也可以引入新的类型,我们来看一下例子:

// 父类继续保持开放

classFather<T>{}

classChildren<T>:Father<T>{}

//关闭父类

classFather<T>{}

classChildren:Father<string>{}

//引入新参数类型

classFather<T>{}

classChildren<T,U>:Father<T>{}

小知识:

封闭参数类型的时候,该类型可以把自己作为具体的类型,例子如下:

classAClass<T>{}

classBClass:AClass<BClass> { }

泛型方法

泛型方法在方法签名内声明类型参数,例如下:

classProgram

{

staticvoidMain(string[] args)

{

GenericFun<int>(124);

}

staticvoidGenericFun<T>(T x, T y)

{

T tmp = x;

x = y;

y = tmp;

Console.WriteLine("x:"+ x + " y:"+ y);

}

}

在上面的代码中我们看到 ```generic.GenericFun<int>(12,4);``` ,我们将int传入泛型方法中,现在我们将这行代码改写成如下形式 ```generic.GenericFun(12,4);```。

我们发现现在这段代码和前面那段代码缺少了 <int> ,那么这么写代码是否有错呢?

答案是要看情况,当编译器可以推断出参数类型的话,我们可以省略掉参数类型,但是当编译器无法推断出参数类型的话我们就必须写上参数类型了。

当然上面这段代码是可以正确运行的,因为编译器可以正确的推断出参数类型。

我们还有如下几点需要注意的:

1. 泛型类中的方法,如果方法引入了参数类型,那它就是泛型方法,反之就不是泛型方法;

2. 除了class、struct、interface、delegate 和方法可以引入类型参数外,属性、字段、索引器、事件和构造函数等都不能声明类型参数,但是可以使用所在泛型类的类型参数。

小知识:

泛型类型和泛型方法可以有多个参数类型,例如 ```class a<T,U>``` 调用方法和单个参数类型一样。结合这一点我们就可以推断出泛型类型和泛型方法可以出现重载,只要参数类型的数量不同就没问题。

在一些情况下我们需要获取参数类型的默认值,这时我们就可以使用default(T)来获得。

约束

我们虽然可以使用所有类型作为泛型类型参数,但是我们在实际开发时很少会这么使用,一般会将类型参数约束到指定的范围内。泛型可用约束如下:

1. base-class:某一个父类的子类;

2. interface:必须是实现了指定的接口;

3. class:必须是引用类型;

4. struct:必须是非空值类型;

5. new:必须包含无参构造函数;

6. U:T:U必须继承T

我们使用的时候是这样的:

classAclass{}

interface Binterface { }

classGeneric1<T> whereT:Aclass { }

classGeneric2<T,U>

whereT:Aclass,Binterface

where U : new

{ }

上面的代码表示 Generic1 类的参数类型T继承自Aclass,Generic2 类的T继承子Aclass,并且实现了 Binterface 接口,而且U包含了无参构造函数。

注意:约束可以用于泛型类型和泛型方法

类型参数与转换

C#种转换支持如下几种:

1. 数值转换;

2. 引用转换;

3. 装箱拆箱转换;

4. 自定义转换。

在发生编译的时候,会根据一直类型的操作数来决定采用那种转换,但是在泛型中我们不知道具体的类型是什么,编译器就会默认使用自定义转换,那么就有可能出现错误。

为了解决这个问题,我们引入了as ,例如我们将传进来的值转换成StringBuilder,这时我们可以这么做:

StringBuilder ToFloat<T>(T t)

{

StringBuilder f = t asStringBuilder;

returnf;

}

variance 转换

讲解variance 转换前,先来简单了解一下协变、逆变和不变。

1. 协变(Covariance):当T作为返回值输出的时候;

2. 逆变(Contravariance):当T作为输出值的时候;

3. 不变(Invariance):当T即是输入又是输出时。

注意:以上这三种就是variance,只能用在接口和委托中。

所谓variance 转换就是上面三种之间的相互转换,variance 转换是引用转换的一个方法,从a转换到b如果是本体转换或者隐式引用转换,那么就是正确的。例如:

IEnumerable<stringtoIEnumerable<object>

IEnumerable<IDisposable> toIEnumerable<object>

作者简介:朱钢,笔名羽生结弦,CSDN博客专家,.NET高级开发工程师,7年一线开发经验,参与过电子政务系统和AI客服系统的开发,以及互联网招聘网站的架构设计,目前就职于北京恒创融慧科技发展有限公司,从事企业级安全监控系统的开发。

为什么有的网站打开速度慢

更新win10系统推送设置方法

win7家庭高级版和旗舰版有什么区别win7家庭高级版是win7系统版本

笔记本外接键盘没反应

教你电脑分辨率怎么调

怎么做淘宝推广实操经验

我观察了10年才发现那些很努力却没有成就的人都有一个特点

iPad23g版可以打电话吗

医院营销模式八大经营理念

外链代发

win7通过高级设置提高电脑性能的方法

谷歌博客搜索使用技巧

教师节的歌曲有关教师节的歌曲推荐

Win7Win81系统如何永久免费升级Win10一招搞定

lol英雄联盟更新失败怎么办

新手站长网站优化快速入门步骤

联系我们

在线服务 外链咨询 二维码

扫码添加微信:juxia_com