《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. STM32定时器时间的计算方法

    本文出自:https://wenku.baidu.com/view/e3bdfb7601f69e31433294c4.htmlSTM32定时器时间的计算方法STM32中的定时器有很多用法:(一)系统时 ...

  2. Java同步学习(持续更新)

    在需要考虑线程安全性的场合,可以考虑以下五种方式来实现线程的安全性: 1.同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,   ...

  3. springboot 的war包在Tomcat中启动失败

    springboot 默认是通常是打包成jar的,里面会内置一个tomcat容器 有时候我们需要使用以前打成war包的方式部署到对应的tomcat中, 具体springboot 怎么从jar改成war ...

  4. laravel中消息通知功能

    以laravel5.5为例子,这个功能laravel自带的有: 1.生成表文件的migration文件,再migrate一下在数据库里生成表.命令为:php artisan notifications ...

  5. CMake,win10,64位,简单配置测试

    https://cmake.org/download/ 下载完成后,解压即可. 创建文件夹,文件路径自己选择: 这里,就近选择在桌面--创建HelloWorld档,在该文档下,分别创建CMakeLis ...

  6. delete content on the right of cursor, Mac

    delete content on the right of cursor, Mac It's not convenient to press Fn+delete to delete content ...

  7. ELK+Beats日志分析系统部署

    一.            名词介绍: E:ElasticSearch 搜索,简称es L:Logstash 管理日志和事件的工具 K:Kibana 功能强大的数据显示客户端 Beats 轻量级数据传 ...

  8. C程序设计第一次实验报告

    C程序设计实验报告 实验项目: 1.字符与ASCII码 2.运算符与表达式的运用 3.顺序结构应用程序 4.数学函数的算法描述 5.鸡兔同笼的算法描述 6.确定坐标的运算描述 姓名:王煜 实验地点:教 ...

  9. git上传文件到coding

    一.上传文件到coding:1.远程连接coding,下载远程仓库到本地git clone https://git.coding.net/wanghao_1/besttest_syz.git 2.cd ...

  10. BBS(第一天)项目之 注册功能实现通过forms验证与 前端ajax请求触发查询数据库判断用户是否存在的功能实现

    1.BBS项目之注册功能通过forms验证 from django import forms from blog.models import User from django.contrib.auth ...