作者|羽生结弦
胡伟
在开发过程中,在同一代码段有许多调用,将使用不同的类型。这被称为跨类型代码重用。通常,我们将使用以下两种方法进行跨类型代码重用:
1.继承;
2.仿制药。
继承表示通过父类的代码重用,而泛型表示通过带有占位符的模板的代码重用,占位符指的是类型。
例如:int、syt和entity等。这部电影主要解释泛型的相关知识。接下来,让我们详细解释泛型。
零,泛型类型
泛型声明类型参数,消费者需要提供类型参数来填充占位符类型。让我们先看一个例子:
publicclassGenericClass<。T>。
{
[]塔拉=纽特·[10];
int position = 0;
公共空隙推动(t)= >塔拉·[位置+]= t;
公共平台= >平台。塔拉·[——位置];
[公共汽车公司。塔拉;
}
classProgram
{
静态主(字符串[)参数
{
var GenericStr = NewGenericCLaSS & lt;字符串>;
普通的。推(& quot张三);
普通的。推(& quot李四);
普通的。推(& quot王武);
普通的。流行音乐;
var GenericInt = NewGenericCLaSS & lt;int>。;
普通的。推动(1);
普通的。推动(2);
普通的。推动(3);
普通的。流行音乐;
}
}
在上面的代码中,当我们将字符串传递给泛型类时,我们将隐式和动态地创建类型。这个操作称为合成,合成将在运行时进行,而不是在编译时。当我们在代码中传递字符串以外的值时,我们将在编译时报告错误。在上面的代码中,我们还看到int被传递到泛型类中,这意味着泛型类可以跨类型重用。
知识贫乏1:
我们将介绍泛型类。T>。它被称为OpenType,而GenericClass & lt字符串>开放类型被称为CloseType,编译后成为封闭类型,所有泛型类型在运行时都是封闭类型,因为占位符已被特定类型填充。
知识贫乏2:
对于每种封闭类型,静态数据都是唯一的,例如:
classProgram
{
静态主(字符串[)参数
{
//输出1
控制台。write line(++my CLaSS & lt;int>。。计数);
//输出2
控制台。write line(++my CLaSS & lt;int>。。计数);
//输出1
控制台。write line(++my CLaSS & lt;字符串>。计数);
}
}
classMyClass<。T>。
{
公共统计;
}
在上面的代码中,我的类中有一个静态字段计数。我们看到前两个调用的输出分别是1和2,但是第三个调用的输出是1。为什么会这样?原因是前两个调用的类型参数与泛型类型的静态字段的类型一致,而第三个调用的类型参数不一致。
在泛型类型子类中,父类参数可以保持打开,父类的类型参数可以关闭。在同一个子类中,可以引入新的类型。让我们看一个例子:
//父类保持打开状态
班级父亲<。T>。{}
classChildren<。T>。:父亲& ltT>。{}
//关闭父类
班级父亲<。T>。{}
班级儿童:父亲& lt字符串>{}
//引入新的参数类型
班级父亲<。T>。{}
classChildren<。t,U>。:父亲& ltT>。{}
知识很少:
封装参数类型时,该类型可以将其自身视为特定类型,例如:
类别类别<。T>。{}
类别类别:类别和lt。类别>。{ }
通用方法
泛型方法在方法签名中声明类型参数,例如:
classProgram
{
静态主(字符串[)参数
{
通用资金<。int>。(12,4);
}
静态通用资金。T>。(T x,T y)
{
T tmp = x。
x = y。
y = tmp。
控制台。write line(& quot;x:& quot;+ x +"。y:"。+y);
}
}
在上面的代码中,我们看到` `泛型。int>。(12,4);```,我们将int传递给泛型方法,现在我们将这一行代码重写为以下形式```` `泛型。普通基金(12,4 (12,4);```` .
我们发现当前代码和以前的代码丢失< int >;写这样的代码有什么错吗?
答案取决于具体情况。当编译器可以推断参数类型时,我们可以省略参数类型,但是当编译器不能推断参数类型时,我们必须编写参数类型。
当然,上述代码可以正确运行,因为编译器可以正确推断参数类型。
我们仍然需要注意以下几点:
1.泛型类中的方法如果引入参数类型,则是泛型方法,否则不是泛型方法;
2.除了类,结构,接口,委托和方法可以引入类型参数,属性,字段,索引器,事件和构造函数不能声明类型参数,但是可以使用泛型类的类型参数。
知识很少:
泛型类型和泛型方法可以有多个参数类型,例如a<类。t,U>。` `调用方法与单个参数类型相同。结合这一点,我们可以推断泛型类型和泛型方法可以重载,只要参数类型的数量不同。
在某些情况下,我们需要获取参数类型的默认值,然后我们可以使用默认值(T)来获取它。
限制
虽然我们可以使用所有类型作为泛型类型参数,但是我们很少在实际开发中使用它们,并且通常将类型参数限制在指定的范围内。通用的可用约束如下:
1.基类:父类的子类;
2.接口:必须实现指定的接口;
3.类:必须是引用类型;
4.结构:必须是非空值类型;
5.new:必须包含无参数构造函数;
你必须继承t
我们就是这样使用它的:
类别类别{}
界面界面界面{ }
classGeneric1<。T>。地点:Aclass { }
类别一般2<。t,U>。
哪里:屁股,脸
哪里是新的
{ }
上面的代码表明Generic1类的参数类型T继承自Aclass,Generic2类的T继承者Aclass实现Binterface接口,并且U包含无参数构造函数。
注意:约束可以用于泛型类型和泛型方法
类型参数和转换
C#转换支持以下内容:
1.数字转换;
2.参考转换;
3.包装和拆包转换;
4.自定义转换。
编译发生时,转换将根据常量类型的操作数决定。然而,在泛型中,如果我们不知道具体类型是什么,编译器将默认使用自定义转换,然后可能会出现错误。
为了解决这个问题,我们引入了,例如,我们将传入的值转换为StringBuilder,然后我们可以这样做:
StringBuilder ToFloat & ltT>。(T)
{
字符串生成器f = tasStringBuilder
returnf
}
方差转换
在解释方差转换之前,让我们简单了解协方差、反演和不变性。
1.协方差:当t作为返回值输出时;
2.反差:当t为输出值时;
3.不变性:当测试既是输入又是输出时。
注意:以上三个是方差,只能在接口和委托中使用。
所谓方差转换是上述三种类型之间的相互转换。方差转换是一种参考转换方法。如果从a到b的转换是本体转换或隐式引用转换,那么它是正确的。例如:
IEnumerable<。字符串>toIEnumerable & lt。对象>;
IEnumerable<。我可以。toIEnumerable & lt。对象>;
作者简介:朱刚,笔名羽生结弦,CSDN博客专家,。NET高级开发工程师,7年一线开发经验,参与电子政务系统和人工智能客户服务系统的开发,以及互联网招聘网站的架构设计。目前,他在北京恒创容晖科技发展有限公司工作,从事企业级安全监控系统的开发。
为什么有些网站打开缓慢
更新win10系统推送设置方法
win 7家庭高级版和旗舰版有什么区别?
笔记本外接键盘无响应
教你如何调整电脑分辨率
如何做淘宝推广实际操作体验
我观察了十年, 只有发现那些努力工作但没有取得成就的人拥有
iPad23g版的特色,你才能打电话给
医院营销模式
外链生成
win7通过高级设置
谷歌博客搜索使用技巧
教师节歌曲推荐
来提高计算机性能的方法