《C#从现象到本质》读书笔记(七)第9章 泛型

泛型的三大好处:类型安全,增强性能(避免装箱和拆箱),代码复用。

泛型方法是传入的参数至少有一个类型为T(尚未制定的类型,根据微软的命名规则,通常以T开头)的方法。T称为类型参数。

它的使用契机一般为:传入类型可能有很多种、但处理方式却相同的情景。这是可以不需要写很多歌重载,而考虑用泛型方法达到代码复用的目的。

同名的泛型方法和非泛型方法会被编译器看做不同的方法。即使都是泛型方法,不同个数的类型参数也会被编译为不同的方法。

泛型约束使得类型参数只能是满足某些条件的类型。它分为如下几类:

1)接口约束。2)基类型约束。基类型约束必须放在其他约束之前。3)构造函数new()约束。new()约束出现在where子句的最后。

多个泛型类型参数,如where T:class where U:struct。

 class Program
{
static void Main(string[] args)
{
var r1 = new Rectangle(, );
var r2 = new Rectangle(, );
Compare(r1, r2, CompareRectangle); var c1 = new Cirtle();
var c2 = new Cirtle();
Compare(c1, c2, CompareCircle); Console.ReadKey();
}
public static int CompareRectangle(Rectangle r1, Rectangle r2)
{
double r1Area = r1.Length * r1.Width;
double r2Area = r2.Length * r2.Width;
if (r1Area > r2Area) return ;
if (r1Area < r2Area) return -;
return ;
}
public static int CompareCircle(Cirtle c1, Cirtle c2)
{
if (c1.Radius > c2.Radius) return ;
if (c1.Radius < c2.Radius) return -;
return ;
}
public static void Compare<T>(T o1, T o2, Func<T, T, int> rule)
{
var ret = rule.Invoke(o1, o2);
if (ret == ) Console.WriteLine("第一个大");
if (ret == -) Console.WriteLine("第二个大");
if (ret == ) Console.WriteLine("一样大");
}
}
public struct Rectangle
{
public double Length { get; set; }
public double Width { get; set; } public Rectangle(double l, double w)
: this()
{
Length = l;
Width = w;
}
}
public struct Cirtle
{
public double Radius { get; set; } public Cirtle(double r)
: this()
{
Radius = r;
}
}

可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用。可变性有两种类型:

1)协变。子类隐式转换为父类,若某方法声明返回类型为object,那么实际上它可以返回任何的类型。

2)逆变。父类隐式转换为子类。

“协变”->”和谐的变”->”很自然的变化”->string->object :协变。

“逆变”->”逆常的变”->”不正常的变化”->object->string 逆变。

协变性和out关键字搭配使用,用于向调用者返回操作的值。接口中的T职能出现在输出中(包括方法的输出、属性的get访问器和委托的参数,因为委托支持协变),不能出现在输入中。

逆变性和in关键字搭配使用,此时类型出现在输入(包括方法的输入、属性的set访问器和委托的参数,因为委托支持逆变)。

协变和逆变体现在泛型类T和T的派生类。out和in关键字只能在接口和委托中使用,不支持泛型方法和泛型类。而且,值类型不参与协变和逆变。

C#中泛型可变性的限制:

1)只有接口和委托可以拥有可变的类型参数。in和out关键字只能用来修饰泛型接口和泛型委托。

2)可变性只能用于引用类型,禁止任何值类型之间的转换,以及值类型和引用类型之间的转换。

3)类型参数使用了out或者ref将禁止可变性。

4)不允许部分可变性。5)多播委托于可变性不能混用。

如果一个接口需要对T协变,那么这个接口所有方法的输入参数类型必须支持对T的逆变。如果接口要支持对T逆变,那么接口中方法的参数类型都必须支持对T协变。

《C#从现象到本质》读书笔记(七)第9章 泛型的更多相关文章

  1. C++ Primer 读书笔记:第11章 泛型算法

    第11章 泛型算法 1.概述 泛型算法依赖于迭代器,而不是依赖容器,需要指定作用的区间,即[开始,结束),表示的区间,如上所示 此外还需要元素是可比的,如果元素本身是不可比的,那么可以自己定义比较函数 ...

  2. SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章)

    SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章) 示例数据库:点我 CHAPTER 08 数据修改 8.1 插入数据 8.1.1 INSERT VALUES 语句 8.1 ...

  3. 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化

    第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...

  4. 《Android开发艺术探索》读书笔记 (3) 第3章 View的事件体系

    本节和<Android群英传>中的第五章Scroll分析有关系,建议先阅读该章的总结 第3章 View的事件体系 3.1 View基本知识 (1)view的层次结构:ViewGroup也是 ...

  5. 《Linux内核设计与实现》读书笔记——第一、 二章

    <Linux内核设计与实现>读书笔记--第一. 二章 标签(空格分隔): 20135321余佳源 第一章 Linux内核简介 1.Unix内核特点 十分简洁:仅提供几百个系统调用并且有明确 ...

  6. MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Max, Min, Count , DistinctCount 以及其它 TopCount, Generate

    MDX 中最大值和最小值 MDX 中最大值和最小值函数的语法和之前看到的 Sum 以及 Aggregate 等聚合函数基本上是一样的: Max( {Set} [, Expression]) Min( ...

  7. 《Android开发艺术探索》读书笔记 (9) 第9章 四大组件的工作过程

    第9章 四大组件的工作过程 9.1 四大组件的运行状态 (1)四大组件中只有BroadcastReceiver既可以在AndroidManifest文件中注册,也可以在代码中注册,其他三个组件都必须在 ...

  8. 【记】《.net之美》之读书笔记(二) C#中的泛型

    前言 上一篇读书笔记,很多小伙伴说这本书很不错,所以趁着国庆假期,继续我的读书之旅,来跟随书中作者一起温习并掌握第二章的内容吧. 一.理解泛型 1.为什么要使用泛型?-----通过使用泛型,可以极大地 ...

  9. Android群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧

    第六章 Android绘图机制与处理技巧 1.屏幕尺寸信息屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DP ...

  10. 【锋利的Jquery】读书笔记七

    第七章  jquery插件 管理cookie的插件--cookie jquery插件太多没什么好讲的,百度太多 说以下 cookie插件 <!DOCTYPE html> <html& ...

随机推荐

  1. redis高可用(主从复制)

    熟练掌握redis需要从 reids如何操作5种基本数据类型,redis如何集群,reids主从复制,redis哨兵机制redis持久化 reids主从复制 的作用可以:实现数据备份,读写分离,集群, ...

  2. 解决mysql使用GTID主从复制错误问题

    做MySQL主从的话肯定会遇到很多同步上的问题,大多数都是由于机器宕机,重启,或者是主键冲突等引起的从服务器停止工作,这里专门收集类似问题并提供整理解决方案,仅供参考. 1.主从网络中断,或主服务器重 ...

  3. eclipse常用快捷键整理

    Ctrl + F11 按上次方式执行 Ctrl + Shift + / 加上注释/**/ Ctrl + Shift + \ 取消注释/**/ Ctrl + / 加上或消除行注释 Ctrl + D 删除 ...

  4. nodejs模块循环引用讲解

    CommonJS 模块的重要特性是加载时执行,即脚本代码在require的时候,就会全部执行.一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出. 让我 ...

  5. Titanic缺失数值处理 & 存活率预测

    1.  kaggle泰坦尼克数据titanic完整下载,原作者良心分享 https://download.csdn.net/download/lansui7312/9936840 2. 缺失值处理 # ...

  6. 1安装Linux

    第二天笔记打卡. 系统安装注意:1.DATE&TIME2.Server with GUI3.分区默认4.网络开启 源代码安装:1.安装难度高2.编译环境复杂3.解决依赖关系 源代码:2.部署编 ...

  7. react-native-pushy 热更新

    教程来源于官网: 准备工作 添加热更新功能 发布应用 说明: 在往 pushy 发布了安装包之后,后续都是通过下面 2个命令来发布 热更新版本的,而不是再次发布安装包, 在使用热更新服务更新版本的时候 ...

  8. ElasicSearch(2) Linux运行

    1.org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearc ...

  9. 20165304《Java程序设计》第九周学习总结

    教材学习内容总结 URL类 URL类是java.net包中的一个重要的类,URL的实例封装着一个统一资源定位符,使用URL创建对象的应用程序称作客户端程序. 一个URL对象通常包含最基本的三部分信息: ...

  10. JavaScript学习-3——数组、函数、递归

    本章目录 -----------①数组 -----------②函数 -----------③递归 一.数组 弱类型:任何类型数据,且没有强度限制: 强类型:同一类型的数据存储的集合(内存中连续存储) ...